]>
Commit | Line | Data |
---|---|---|
b34c74ab JB |
1 | /* Self tests of the gmp-utils API. |
2 | ||
3666a048 | 3 | Copyright (C) 2019-2021 Free Software Foundation, Inc. |
b34c74ab JB |
4 | |
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "gmp-utils.h" | |
21 | #include "gdbsupport/selftest.h" | |
22 | ||
23 | #include <math.h> | |
24 | ||
25 | namespace selftests { | |
26 | ||
27 | /* Perform a series of general tests of gdb_mpz's as_integer method. | |
28 | ||
63c457b9 JB |
29 | This function limits itself to values which are in range (out-of-range |
30 | values will be tested separately). In doing so, it tries to be reasonably | |
31 | exhaustive, by testing the edges, as well as a resonable set of values | |
32 | including negative ones, zero, and positive values. */ | |
b34c74ab JB |
33 | |
34 | static void | |
35 | gdb_mpz_as_integer () | |
36 | { | |
37 | /* Test a range of values, both as LONGEST and ULONGEST. */ | |
38 | gdb_mpz v; | |
39 | LONGEST l_expected; | |
40 | ULONGEST ul_expected; | |
41 | ||
42 | /* Start with the smallest LONGEST */ | |
43 | l_expected = (LONGEST) 1 << (sizeof (LONGEST) * 8 - 1); | |
44 | ||
45 | mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8 - 1); | |
46 | mpz_neg (v.val, v.val); | |
47 | ||
48 | SELF_CHECK (v.as_integer<LONGEST> () == l_expected); | |
49 | ||
50 | /* Try with a small range of integers including negative, zero, | |
51 | and positive values. */ | |
52 | for (int i = -256; i <= 256; i++) | |
53 | { | |
54 | l_expected = (LONGEST) i; | |
55 | mpz_set_si (v.val, i); | |
56 | SELF_CHECK (v.as_integer<LONGEST> () == l_expected); | |
57 | ||
58 | if (i >= 0) | |
59 | { | |
60 | ul_expected = (ULONGEST) i; | |
61 | mpz_set_ui (v.val, i); | |
62 | SELF_CHECK (v.as_integer<ULONGEST> () == ul_expected); | |
63 | } | |
64 | } | |
65 | ||
66 | /* Try with LONGEST_MAX. */ | |
67 | l_expected = LONGEST_MAX; | |
68 | ul_expected = (ULONGEST) l_expected; | |
69 | ||
70 | mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8 - 1); | |
71 | mpz_sub_ui (v.val, v.val, 1); | |
72 | ||
73 | SELF_CHECK (v.as_integer<LONGEST> () == l_expected); | |
74 | SELF_CHECK (v.as_integer<ULONGEST> () == ul_expected); | |
75 | ||
76 | /* Try with ULONGEST_MAX. */ | |
77 | ul_expected = ULONGEST_MAX; | |
78 | mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8); | |
79 | mpz_sub_ui (v.val, v.val, 1); | |
80 | ||
81 | SELF_CHECK (v.as_integer<ULONGEST> () == ul_expected); | |
82 | } | |
83 | ||
63c457b9 JB |
84 | /* A helper function which calls the given gdb_mpz object's as_integer |
85 | method with the given type T, and verifies that this triggers | |
86 | an error due to VAL's value being out of range for type T. */ | |
87 | ||
88 | template<typename T, typename = gdb::Requires<std::is_integral<T>>> | |
89 | static void | |
90 | check_as_integer_raises_out_of_range_error (const gdb_mpz &val) | |
91 | { | |
92 | try | |
93 | { | |
94 | val.as_integer<T> (); | |
95 | } | |
96 | catch (const gdb_exception_error &ex) | |
97 | { | |
98 | SELF_CHECK (ex.reason == RETURN_ERROR); | |
99 | SELF_CHECK (ex.error == GENERIC_ERROR); | |
100 | SELF_CHECK (strstr (ex.what (), "Cannot export value") != nullptr); | |
101 | return; | |
102 | } | |
103 | /* The expected exception did not get raised. */ | |
104 | SELF_CHECK (false); | |
105 | } | |
106 | ||
107 | /* Perform out-of-range tests of gdb_mpz's as_integer method. | |
108 | ||
109 | The goal of this function is to verify that gdb_mpz::as_integer | |
110 | handles out-of-range values correctly. */ | |
111 | ||
112 | static void | |
113 | gdb_mpz_as_integer_out_of_range () | |
114 | { | |
115 | gdb_mpz v; | |
116 | ||
117 | /* Try LONGEST_MIN minus 1. */ | |
118 | mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8 - 1); | |
119 | mpz_neg (v.val, v.val); | |
120 | mpz_sub_ui (v.val, v.val, 1); | |
121 | ||
122 | check_as_integer_raises_out_of_range_error<ULONGEST> (v); | |
123 | check_as_integer_raises_out_of_range_error<LONGEST> (v); | |
124 | ||
125 | /* Try negative one (-1). */ | |
126 | v = -1; | |
127 | ||
128 | check_as_integer_raises_out_of_range_error<ULONGEST> (v); | |
129 | SELF_CHECK (v.as_integer<LONGEST> () == (LONGEST) -1); | |
130 | ||
131 | /* Try LONGEST_MAX plus 1. */ | |
132 | v = LONGEST_MAX; | |
133 | mpz_add_ui (v.val, v.val, 1); | |
134 | ||
135 | SELF_CHECK (v.as_integer<ULONGEST> () == (ULONGEST) LONGEST_MAX + 1); | |
136 | check_as_integer_raises_out_of_range_error<LONGEST> (v); | |
137 | ||
138 | /* Try ULONGEST_MAX plus 1. */ | |
139 | v = ULONGEST_MAX; | |
140 | mpz_add_ui (v.val, v.val, 1); | |
141 | ||
142 | check_as_integer_raises_out_of_range_error<ULONGEST> (v); | |
143 | check_as_integer_raises_out_of_range_error<LONGEST> (v); | |
144 | } | |
145 | ||
b34c74ab JB |
146 | /* A helper function to store the given integer value into a buffer, |
147 | before reading it back into a gdb_mpz. Sets ACTUAL to the value | |
148 | read back, while at the same time setting EXPECTED as the value | |
149 | we would expect to be read back. | |
150 | ||
151 | Note that this function does not perform the comparison between | |
152 | EXPECTED and ACTUAL. The caller will do it inside a SELF_CHECK | |
153 | call, allowing the line information shown when the test fails | |
154 | to provide a bit more information about the kind of values | |
155 | that were used when the check failed. This makes the writing | |
156 | of the tests a little more verbose, but the debugging in case | |
157 | of problems should hopefuly be easier. */ | |
158 | ||
159 | template<typename T> | |
160 | void | |
c9f0b43f | 161 | store_and_read_back (T val, size_t buf_len, enum bfd_endian byte_order, |
b34c74ab JB |
162 | gdb_mpz &expected, gdb_mpz &actual) |
163 | { | |
164 | gdb_byte *buf; | |
165 | ||
166 | expected = val; | |
167 | ||
168 | buf = (gdb_byte *) alloca (buf_len); | |
169 | store_integer (buf, buf_len, byte_order, val); | |
170 | ||
171 | /* Pre-initialize ACTUAL to something that's not the expected value. */ | |
172 | mpz_set (actual.val, expected.val); | |
173 | mpz_sub_ui (actual.val, actual.val, 500); | |
174 | ||
c9f0b43f | 175 | actual.read ({buf, buf_len}, byte_order, !std::is_signed<T>::value); |
b34c74ab JB |
176 | } |
177 | ||
178 | /* Test the gdb_mpz::read method over a reasonable range of values. | |
179 | ||
180 | The testing is done by picking an arbitrary buffer length, after | |
181 | which we test every possible value that this buffer allows, both | |
182 | with signed numbers as well as unsigned ones. */ | |
183 | ||
184 | static void | |
185 | gdb_mpz_read_all_from_small () | |
186 | { | |
187 | /* Start with a type whose size is small enough that we can afford | |
188 | to check the complete range. */ | |
189 | ||
190 | int buf_len = 1; | |
c0ad05d5 SM |
191 | LONGEST l_min = -pow (2.0, buf_len * 8 - 1); |
192 | LONGEST l_max = pow (2.0, buf_len * 8 - 1) - 1; | |
b34c74ab JB |
193 | |
194 | for (LONGEST l = l_min; l <= l_max; l++) | |
195 | { | |
196 | gdb_mpz expected, actual; | |
197 | ||
198 | store_and_read_back (l, buf_len, BFD_ENDIAN_BIG, expected, actual); | |
199 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
200 | ||
201 | store_and_read_back (l, buf_len, BFD_ENDIAN_LITTLE, expected, actual); | |
202 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
203 | } | |
204 | ||
205 | /* Do the same as above, but with an unsigned type. */ | |
206 | ULONGEST ul_min = 0; | |
c0ad05d5 | 207 | ULONGEST ul_max = pow (2.0, buf_len * 8) - 1; |
b34c74ab JB |
208 | |
209 | for (ULONGEST ul = ul_min; ul <= ul_max; ul++) | |
210 | { | |
211 | gdb_mpz expected, actual; | |
212 | ||
213 | store_and_read_back (ul, buf_len, BFD_ENDIAN_BIG, expected, actual); | |
214 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
215 | ||
216 | store_and_read_back (ul, buf_len, BFD_ENDIAN_LITTLE, expected, actual); | |
217 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
218 | } | |
219 | } | |
220 | ||
221 | /* Test the gdb_mpz::read the extremes of LONGEST and ULONGEST. */ | |
222 | ||
223 | static void | |
224 | gdb_mpz_read_min_max () | |
225 | { | |
226 | gdb_mpz expected, actual; | |
227 | ||
228 | /* Start with the smallest LONGEST. */ | |
229 | ||
230 | LONGEST l_min = (LONGEST) 1 << (sizeof (LONGEST) * 8 - 1); | |
231 | ||
232 | store_and_read_back (l_min, sizeof (LONGEST), BFD_ENDIAN_BIG, | |
233 | expected, actual); | |
234 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
235 | ||
236 | store_and_read_back (l_min, sizeof (LONGEST), BFD_ENDIAN_LITTLE, | |
237 | expected, actual); | |
238 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
239 | ||
240 | /* Same with LONGEST_MAX. */ | |
241 | ||
242 | LONGEST l_max = LONGEST_MAX; | |
243 | ||
244 | store_and_read_back (l_max, sizeof (LONGEST), BFD_ENDIAN_BIG, | |
245 | expected, actual); | |
246 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
247 | ||
248 | store_and_read_back (l_max, sizeof (LONGEST), BFD_ENDIAN_LITTLE, | |
249 | expected, actual); | |
250 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
251 | ||
252 | /* Same with the smallest ULONGEST. */ | |
253 | ||
254 | ULONGEST ul_min = 0; | |
255 | ||
256 | store_and_read_back (ul_min, sizeof (ULONGEST), BFD_ENDIAN_BIG, | |
257 | expected, actual); | |
258 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
259 | ||
260 | store_and_read_back (ul_min, sizeof (ULONGEST), BFD_ENDIAN_LITTLE, | |
261 | expected, actual); | |
262 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
263 | ||
264 | /* Same with ULONGEST_MAX. */ | |
265 | ||
266 | ULONGEST ul_max = ULONGEST_MAX; | |
267 | ||
268 | store_and_read_back (ul_max, sizeof (ULONGEST), BFD_ENDIAN_BIG, | |
269 | expected, actual); | |
270 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
271 | ||
272 | store_and_read_back (ul_max, sizeof (ULONGEST), BFD_ENDIAN_LITTLE, | |
273 | expected, actual); | |
274 | SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0); | |
275 | } | |
276 | ||
277 | /* A helper function which creates a gdb_mpz object from the given | |
278 | integer VAL, and then writes it using its gdb_mpz::write method. | |
279 | ||
280 | The written value is then extracted from the buffer and returned, | |
281 | for comparison with the original. | |
282 | ||
283 | Note that this function does not perform the comparison between | |
284 | VAL and the returned value. The caller will do it inside a SELF_CHECK | |
285 | call, allowing the line information shown when the test fails | |
286 | to provide a bit more information about the kind of values | |
287 | that were used when the check failed. This makes the writing | |
288 | of the tests a little more verbose, but the debugging in case | |
289 | of problems should hopefuly be easier. */ | |
290 | ||
291 | template<typename T> | |
292 | T | |
c9f0b43f | 293 | write_and_extract (T val, size_t buf_len, enum bfd_endian byte_order) |
b34c74ab JB |
294 | { |
295 | gdb_mpz v (val); | |
296 | ||
297 | SELF_CHECK (v.as_integer<T> () == val); | |
298 | ||
299 | gdb_byte *buf = (gdb_byte *) alloca (buf_len); | |
c9f0b43f | 300 | v.write ({buf, buf_len}, byte_order, !std::is_signed<T>::value); |
b34c74ab JB |
301 | |
302 | return extract_integer<T> (buf, buf_len, byte_order); | |
303 | } | |
304 | ||
305 | /* Test the gdb_mpz::write method over a reasonable range of values. | |
306 | ||
307 | The testing is done by picking an arbitrary buffer length, after | |
308 | which we test every possible value that this buffer allows. */ | |
309 | ||
310 | static void | |
311 | gdb_mpz_write_all_from_small () | |
312 | { | |
313 | int buf_len = 1; | |
c0ad05d5 SM |
314 | LONGEST l_min = -pow (2.0, buf_len * 8 - 1); |
315 | LONGEST l_max = pow (2.0, buf_len * 8 - 1) - 1; | |
b34c74ab JB |
316 | |
317 | for (LONGEST l = l_min; l <= l_max; l++) | |
318 | { | |
319 | SELF_CHECK (write_and_extract (l, buf_len, BFD_ENDIAN_BIG) == l); | |
320 | SELF_CHECK (write_and_extract (l, buf_len, BFD_ENDIAN_LITTLE) == l); | |
321 | } | |
322 | ||
323 | /* Do the same as above, but with an unsigned type. */ | |
324 | ULONGEST ul_min = 0; | |
c0ad05d5 | 325 | ULONGEST ul_max = pow (2.0, buf_len * 8) - 1; |
b34c74ab JB |
326 | |
327 | for (ULONGEST ul = ul_min; ul <= ul_max; ul++) | |
328 | { | |
329 | SELF_CHECK (write_and_extract (ul, buf_len, BFD_ENDIAN_BIG) == ul); | |
330 | SELF_CHECK (write_and_extract (ul, buf_len, BFD_ENDIAN_LITTLE) == ul); | |
331 | } | |
332 | } | |
333 | ||
334 | /* Test the gdb_mpz::write the extremes of LONGEST and ULONGEST. */ | |
335 | ||
336 | static void | |
337 | gdb_mpz_write_min_max () | |
338 | { | |
339 | /* Start with the smallest LONGEST. */ | |
340 | ||
341 | LONGEST l_min = (LONGEST) 1 << (sizeof (LONGEST) * 8 - 1); | |
342 | SELF_CHECK (write_and_extract (l_min, sizeof (LONGEST), BFD_ENDIAN_BIG) | |
343 | == l_min); | |
344 | SELF_CHECK (write_and_extract (l_min, sizeof (LONGEST), BFD_ENDIAN_LITTLE) | |
345 | == l_min); | |
346 | ||
347 | /* Same with LONGEST_MAX. */ | |
348 | ||
349 | LONGEST l_max = LONGEST_MAX; | |
350 | SELF_CHECK (write_and_extract (l_max, sizeof (LONGEST), BFD_ENDIAN_BIG) | |
351 | == l_max); | |
352 | SELF_CHECK (write_and_extract (l_max, sizeof (LONGEST), BFD_ENDIAN_LITTLE) | |
353 | == l_max); | |
354 | ||
355 | /* Same with the smallest ULONGEST. */ | |
356 | ||
357 | ULONGEST ul_min = (ULONGEST) 1 << (sizeof (ULONGEST) * 8 - 1); | |
358 | SELF_CHECK (write_and_extract (ul_min, sizeof (ULONGEST), BFD_ENDIAN_BIG) | |
359 | == ul_min); | |
360 | SELF_CHECK (write_and_extract (ul_min, sizeof (ULONGEST), BFD_ENDIAN_LITTLE) | |
361 | == ul_min); | |
362 | ||
363 | /* Same with ULONGEST_MAX. */ | |
364 | ||
365 | ULONGEST ul_max = ULONGEST_MAX; | |
366 | SELF_CHECK (write_and_extract (ul_max, sizeof (ULONGEST), BFD_ENDIAN_BIG) | |
367 | == ul_max); | |
368 | SELF_CHECK (write_and_extract (ul_max, sizeof (ULONGEST), BFD_ENDIAN_LITTLE) | |
369 | == ul_max); | |
370 | } | |
371 | ||
372 | /* A helper function which stores the signed number, the unscaled value | |
373 | of a fixed point object, into a buffer, and then uses gdb_mpq's | |
374 | read_fixed_point to read it as a fixed_point value, with | |
375 | the given parameters. | |
376 | ||
377 | EXPECTED is set to the value we expected to get after the call | |
378 | to read_fixed_point. ACTUAL is the value we actually do get. | |
379 | ||
380 | Note that this function does not perform the comparison between | |
381 | EXPECTED and ACTUAL. The caller will do it inside a SELF_CHECK | |
382 | call, allowing the line information shown when the test fails | |
383 | to provide a bit more information about the kind of values | |
384 | that were used when the check failed. This makes the writing | |
385 | of the tests a little more verbose, but the debugging in case | |
386 | of problems should hopefuly be easier. */ | |
387 | ||
388 | static void | |
389 | read_fp_test (int unscaled, const gdb_mpq &scaling_factor, | |
390 | enum bfd_endian byte_order, | |
391 | gdb_mpq &expected, gdb_mpq &actual) | |
392 | { | |
393 | /* For this kind of testing, we'll use a buffer the same size as | |
394 | our unscaled parameter. */ | |
c9f0b43f | 395 | const size_t len = sizeof (unscaled); |
b34c74ab JB |
396 | gdb_byte buf[len]; |
397 | store_signed_integer (buf, len, byte_order, unscaled); | |
398 | ||
c9f0b43f | 399 | actual.read_fixed_point ({buf, len}, byte_order, 0, scaling_factor); |
b34c74ab JB |
400 | |
401 | mpq_set_si (expected.val, unscaled, 1); | |
402 | mpq_mul (expected.val, expected.val, scaling_factor.val); | |
403 | } | |
404 | ||
405 | /* Perform various tests of the gdb_mpq::read_fixed_point method. */ | |
406 | ||
407 | static void | |
408 | gdb_mpq_read_fixed_point () | |
409 | { | |
410 | gdb_mpq expected, actual; | |
411 | gdb_mpq scaling_factor; | |
412 | ||
413 | /* Pick an arbitrary scaling_factor; this operation is trivial enough | |
414 | thanks to GMP that the value we use isn't really important. */ | |
415 | mpq_set_ui (scaling_factor.val, 3, 5); | |
416 | ||
417 | /* Try a few values, both negative and positive... */ | |
418 | ||
419 | read_fp_test (-256, scaling_factor, BFD_ENDIAN_BIG, expected, actual); | |
420 | SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0); | |
421 | read_fp_test (-256, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual); | |
422 | SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0); | |
423 | ||
424 | read_fp_test (-1, scaling_factor, BFD_ENDIAN_BIG, expected, actual); | |
425 | SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0); | |
426 | read_fp_test (-1, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual); | |
427 | SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0); | |
428 | ||
429 | read_fp_test (0, scaling_factor, BFD_ENDIAN_BIG, expected, actual); | |
430 | SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0); | |
431 | read_fp_test (0, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual); | |
432 | SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0); | |
433 | ||
434 | read_fp_test (1, scaling_factor, BFD_ENDIAN_BIG, expected, actual); | |
435 | SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0); | |
436 | read_fp_test (1, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual); | |
437 | SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0); | |
438 | ||
439 | read_fp_test (1025, scaling_factor, BFD_ENDIAN_BIG, expected, actual); | |
440 | SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0); | |
441 | read_fp_test (1025, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual); | |
442 | SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0); | |
443 | } | |
444 | ||
445 | /* A helper function which builds a gdb_mpq object from the given | |
446 | NUMERATOR and DENOMINATOR, and then calls gdb_mpq's write_fixed_point | |
447 | method to write it to a buffer. | |
448 | ||
449 | The value written into the buffer is then read back as is, | |
450 | and returned. */ | |
451 | ||
452 | static LONGEST | |
453 | write_fp_test (int numerator, unsigned int denominator, | |
454 | const gdb_mpq &scaling_factor, | |
455 | enum bfd_endian byte_order) | |
456 | { | |
457 | /* For this testing, we'll use a buffer the size of LONGEST. | |
458 | This is really an arbitrary decision, as long as the buffer | |
459 | is long enough to hold the unscaled values that we'll be | |
460 | writing. */ | |
c9f0b43f | 461 | const size_t len = sizeof (LONGEST); |
b34c74ab JB |
462 | gdb_byte buf[len]; |
463 | memset (buf, 0, len); | |
464 | ||
465 | gdb_mpq v; | |
4fbb7cce | 466 | mpq_set_si (v.val, numerator, denominator); |
b34c74ab | 467 | mpq_canonicalize (v.val); |
c9f0b43f | 468 | v.write_fixed_point ({buf, len}, byte_order, 0, scaling_factor); |
b34c74ab JB |
469 | |
470 | return extract_unsigned_integer (buf, len, byte_order); | |
471 | } | |
472 | ||
473 | /* Perform various tests of the gdb_mpq::write_fixed_point method. */ | |
474 | ||
475 | static void | |
476 | gdb_mpq_write_fixed_point () | |
477 | { | |
478 | /* Pick an arbitrary factor; this operations is sufficiently trivial | |
479 | with the use of GMP that the value of this factor is not really | |
480 | all that important. */ | |
481 | gdb_mpq scaling_factor; | |
482 | mpq_set_ui (scaling_factor.val, 1, 3); | |
483 | ||
484 | gdb_mpq vq; | |
485 | ||
486 | /* Try a few multiples of the scaling factor, both negative, | |
487 | and positive... */ | |
488 | ||
489 | SELF_CHECK (write_fp_test (-8, 1, scaling_factor, BFD_ENDIAN_BIG) == -24); | |
490 | SELF_CHECK (write_fp_test (-8, 1, scaling_factor, BFD_ENDIAN_LITTLE) == -24); | |
491 | ||
492 | SELF_CHECK (write_fp_test (-2, 3, scaling_factor, BFD_ENDIAN_BIG) == -2); | |
493 | SELF_CHECK (write_fp_test (-2, 3, scaling_factor, BFD_ENDIAN_LITTLE) == -2); | |
494 | ||
495 | SELF_CHECK (write_fp_test (0, 3, scaling_factor, BFD_ENDIAN_BIG) == 0); | |
496 | SELF_CHECK (write_fp_test (0, 3, scaling_factor, BFD_ENDIAN_LITTLE) == 0); | |
497 | ||
498 | SELF_CHECK (write_fp_test (5, 3, scaling_factor, BFD_ENDIAN_BIG) == 5); | |
499 | SELF_CHECK (write_fp_test (5, 3, scaling_factor, BFD_ENDIAN_LITTLE) == 5); | |
500 | } | |
501 | ||
502 | } | |
503 | ||
504 | void _initialize_gmp_utils_selftests (); | |
505 | ||
506 | void | |
507 | _initialize_gmp_utils_selftests () | |
508 | { | |
509 | selftests::register_test ("gdb_mpz_as_integer", | |
510 | selftests::gdb_mpz_as_integer); | |
63c457b9 JB |
511 | selftests::register_test ("gdb_mpz_as_integer_out_of_range", |
512 | selftests::gdb_mpz_as_integer_out_of_range); | |
b34c74ab JB |
513 | selftests::register_test ("gdb_mpz_read_all_from_small", |
514 | selftests::gdb_mpz_read_all_from_small); | |
515 | selftests::register_test ("gdb_mpz_read_min_max", | |
516 | selftests::gdb_mpz_read_min_max); | |
517 | selftests::register_test ("gdb_mpz_write_all_from_small", | |
518 | selftests::gdb_mpz_write_all_from_small); | |
519 | selftests::register_test ("gdb_mpz_write_min_max", | |
520 | selftests::gdb_mpz_write_min_max); | |
521 | selftests::register_test ("gdb_mpq_read_fixed_point", | |
522 | selftests::gdb_mpq_read_fixed_point); | |
523 | selftests::register_test ("gdb_mpq_write_fixed_point", | |
524 | selftests::gdb_mpq_write_fixed_point); | |
525 | } |