Updated Swedish translation for the opcodes directory
[binutils-gdb.git] / gdb / gmp-utils.h
bloba5c27feb59ff87006bc272d299048df1a13a67dc
1 /* Miscellaneous routines making it easier to use GMP within GDB's framework.
3 Copyright (C) 2019-2023 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #ifndef GMP_UTILS_H
21 #define GMP_UTILS_H
23 /* Include <stdio.h> and <stdarg.h> ahead of <gmp.h>, so as to get
24 access to GMP's various formatting functions. */
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <gmp.h>
28 #include "gdbsupport/traits.h"
30 /* Same as gmp_asprintf, but returning an std::string. */
32 std::string gmp_string_printf (const char *fmt, ...);
34 struct gdb_mpq;
35 struct gdb_mpf;
37 /* A class to make it easier to use GMP's mpz_t values within GDB. */
39 struct gdb_mpz
41 /* Constructors. */
42 gdb_mpz () { mpz_init (m_val); }
44 explicit gdb_mpz (const mpz_t &from_val)
46 mpz_init (m_val);
47 mpz_set (m_val, from_val);
50 gdb_mpz (const gdb_mpz &from)
52 mpz_init (m_val);
53 mpz_set (m_val, from.m_val);
56 /* Initialize using the given integral value.
58 The main advantage of this method is that it handles both signed
59 and unsigned types, with no size restriction. */
60 template<typename T, typename = gdb::Requires<std::is_integral<T>>>
61 explicit gdb_mpz (T src)
63 mpz_init (m_val);
64 set (src);
67 explicit gdb_mpz (gdb_mpz &&from)
69 mpz_init (m_val);
70 mpz_swap (m_val, from.m_val);
74 gdb_mpz &operator= (const gdb_mpz &from)
76 mpz_set (m_val, from.m_val);
77 return *this;
80 gdb_mpz &operator= (gdb_mpz &&other)
82 mpz_swap (m_val, other.m_val);
83 return *this;
86 template<typename T, typename = gdb::Requires<std::is_integral<T>>>
87 gdb_mpz &operator= (T src)
89 set (src);
90 return *this;
93 gdb_mpz &operator= (bool src)
95 mpz_set_ui (m_val, (unsigned long) src);
96 return *this;
99 /* Initialize this value from a string and a base. Returns true if
100 the string was parsed successfully, false otherwise. */
101 bool set (const char *str, int base)
103 return mpz_set_str (m_val, str, base) != -1;
106 /* Return a new value that is BASE**EXP. */
107 static gdb_mpz pow (unsigned long base, unsigned long exp)
109 gdb_mpz result;
110 mpz_ui_pow_ui (result.m_val, base, exp);
111 return result;
114 /* Return a new value that is this value raised to EXP. */
115 gdb_mpz pow (unsigned long exp) const
117 gdb_mpz result;
118 mpz_pow_ui (result.m_val, m_val, exp);
119 return result;
122 /* Convert this value to an integer of the given type.
124 The return type can signed or unsigned, with no size restriction. */
125 template<typename T> T as_integer () const;
127 /* Convert this value to an integer of the given type. If this
128 value is too large, it is truncated.
130 The return type can signed or unsigned, with no size restriction. */
131 template<typename T> T as_integer_truncate () const;
133 /* Set VAL by importing the number stored in the byte array (BUF),
134 using the given BYTE_ORDER. The size of the data to read is
135 the byte array's size.
137 UNSIGNED_P indicates whether the number has an unsigned type. */
138 void read (gdb::array_view<const gdb_byte> buf, enum bfd_endian byte_order,
139 bool unsigned_p);
141 /* Write VAL into BUF as a number whose byte size is the size of BUF,
142 using the given BYTE_ORDER.
144 UNSIGNED_P indicates whether the number has an unsigned type. */
145 void write (gdb::array_view<gdb_byte> buf, enum bfd_endian byte_order,
146 bool unsigned_p) const
148 export_bits (buf, byte_order == BFD_ENDIAN_BIG ? 1 : -1 /* endian */,
149 unsigned_p, true /* safe */);
152 /* Like write, but truncates the value to the desired number of
153 bytes. */
154 void truncate (gdb::array_view<gdb_byte> buf, enum bfd_endian byte_order,
155 bool unsigned_p) const
157 export_bits (buf, byte_order == BFD_ENDIAN_BIG ? 1 : -1 /* endian */,
158 unsigned_p, false /* safe */);
161 /* Return a string containing VAL. */
162 std::string str () const { return gmp_string_printf ("%Zd", m_val); }
164 /* The destructor. */
165 ~gdb_mpz () { mpz_clear (m_val); }
167 /* Negate this value in place. */
168 void negate ()
170 mpz_neg (m_val, m_val);
173 /* Take the one's complement in place. */
174 void complement ()
175 { mpz_com (m_val, m_val); }
177 /* Mask this value to N bits, in place. */
178 void mask (unsigned n)
179 { mpz_tdiv_r_2exp (m_val, m_val, n); }
181 /* Return the sign of this value. This returns -1 for a negative
182 value, 0 if the value is 0, and 1 for a positive value. */
183 int sgn () const
184 { return mpz_sgn (m_val); }
186 explicit operator bool () const
187 { return sgn () != 0; }
189 gdb_mpz &operator*= (long other)
191 mpz_mul_si (m_val, m_val, other);
192 return *this;
195 gdb_mpz operator* (const gdb_mpz &other) const
197 gdb_mpz result;
198 mpz_mul (result.m_val, m_val, other.m_val);
199 return result;
202 gdb_mpz operator/ (const gdb_mpz &other) const
204 gdb_mpz result;
205 mpz_tdiv_q (result.m_val, m_val, other.m_val);
206 return result;
209 gdb_mpz operator% (const gdb_mpz &other) const
211 gdb_mpz result;
212 mpz_tdiv_r (result.m_val, m_val, other.m_val);
213 return result;
216 gdb_mpz &operator+= (unsigned long other)
218 mpz_add_ui (m_val, m_val, other);
219 return *this;
222 gdb_mpz &operator+= (const gdb_mpz &other)
224 mpz_add (m_val, m_val, other.m_val);
225 return *this;
228 gdb_mpz operator+ (const gdb_mpz &other) const
230 gdb_mpz result;
231 mpz_add (result.m_val, m_val, other.m_val);
232 return result;
235 gdb_mpz &operator-= (unsigned long other)
237 mpz_sub_ui (m_val, m_val, other);
238 return *this;
241 gdb_mpz &operator-= (const gdb_mpz &other)
243 mpz_sub (m_val, m_val, other.m_val);
244 return *this;
247 gdb_mpz operator- (const gdb_mpz &other) const
249 gdb_mpz result;
250 mpz_sub (result.m_val, m_val, other.m_val);
251 return result;
254 gdb_mpz &operator<<= (unsigned long nbits)
256 mpz_mul_2exp (m_val, m_val, nbits);
257 return *this;
260 gdb_mpz operator<< (unsigned long nbits) const
262 gdb_mpz result;
263 mpz_mul_2exp (result.m_val, m_val, nbits);
264 return result;
267 gdb_mpz operator>> (unsigned long nbits) const
269 gdb_mpz result;
270 mpz_tdiv_q_2exp (result.m_val, m_val, nbits);
271 return result;
274 gdb_mpz &operator>>= (unsigned long nbits)
276 mpz_tdiv_q_2exp (m_val, m_val, nbits);
277 return *this;
280 gdb_mpz operator& (const gdb_mpz &other) const
282 gdb_mpz result;
283 mpz_and (result.m_val, m_val, other.m_val);
284 return result;
287 gdb_mpz operator| (const gdb_mpz &other) const
289 gdb_mpz result;
290 mpz_ior (result.m_val, m_val, other.m_val);
291 return result;
294 gdb_mpz operator^ (const gdb_mpz &other) const
296 gdb_mpz result;
297 mpz_xor (result.m_val, m_val, other.m_val);
298 return result;
301 bool operator> (const gdb_mpz &other) const
303 return mpz_cmp (m_val, other.m_val) > 0;
306 bool operator>= (const gdb_mpz &other) const
308 return mpz_cmp (m_val, other.m_val) >= 0;
311 bool operator< (const gdb_mpz &other) const
313 return mpz_cmp (m_val, other.m_val) < 0;
316 bool operator<= (const gdb_mpz &other) const
318 return mpz_cmp (m_val, other.m_val) <= 0;
321 bool operator< (long other) const
323 return mpz_cmp_si (m_val, other) < 0;
326 /* We want an operator== that can handle all integer types. For
327 types that are 'long' or narrower, we can use a GMP function and
328 avoid boxing the RHS. But, because overloading based on integer
329 type is a pain in C++, we accept all such types here and check
330 the size in the body. */
331 template<typename T, typename = gdb::Requires<std::is_integral<T>>>
332 bool operator== (T other) const
334 if (std::is_signed<T>::value)
336 if (sizeof (T) <= sizeof (long))
337 return mpz_cmp_si (m_val, other) == 0;
339 else
341 if (sizeof (T) <= sizeof (unsigned long))
342 return mpz_cmp_ui (m_val, other) == 0;
344 return *this == gdb_mpz (other);
347 bool operator== (const gdb_mpz &other) const
349 return mpz_cmp (m_val, other.m_val) == 0;
352 bool operator!= (const gdb_mpz &other) const
354 return mpz_cmp (m_val, other.m_val) != 0;
357 private:
359 /* Helper template for constructor and operator=. */
360 template<typename T> void set (T src);
362 /* Low-level function to export VAL into BUF as a number whose byte size
363 is the size of BUF.
365 If UNSIGNED_P is true, then export VAL into BUF as an unsigned value.
366 Otherwise, export it as a signed value.
368 The API is inspired from GMP's mpz_export, hence the naming and types
369 of the following parameter:
370 - ENDIAN should be:
371 . 1 for most significant byte first; or
372 . -1 for least significant byte first; or
373 . 0 for native endianness.
375 If SAFE is true, an error is raised if BUF is not large enough to
376 contain the value being exported. If SAFE is false, the value is
377 truncated to fit in BUF. */
378 void export_bits (gdb::array_view<gdb_byte> buf, int endian, bool unsigned_p,
379 bool safe) const;
381 friend struct gdb_mpq;
382 friend struct gdb_mpf;
384 mpz_t m_val;
387 /* A class to make it easier to use GMP's mpq_t values within GDB. */
389 struct gdb_mpq
391 /* Constructors. */
392 gdb_mpq () { mpq_init (m_val); }
394 explicit gdb_mpq (const mpq_t &from_val)
396 mpq_init (m_val);
397 mpq_set (m_val, from_val);
400 gdb_mpq (const gdb_mpq &from)
402 mpq_init (m_val);
403 mpq_set (m_val, from.m_val);
406 explicit gdb_mpq (gdb_mpq &&from)
408 mpq_init (m_val);
409 mpq_swap (m_val, from.m_val);
412 gdb_mpq (const gdb_mpz &num, const gdb_mpz &denom)
414 mpq_init (m_val);
415 mpz_set (mpq_numref (m_val), num.m_val);
416 mpz_set (mpq_denref (m_val), denom.m_val);
417 mpq_canonicalize (m_val);
420 gdb_mpq (long num, long denom)
422 mpq_init (m_val);
423 mpq_set_si (m_val, num, denom);
424 mpq_canonicalize (m_val);
427 /* Copy assignment operator. */
428 gdb_mpq &operator= (const gdb_mpq &from)
430 mpq_set (m_val, from.m_val);
431 return *this;
434 gdb_mpq &operator= (gdb_mpq &&from)
436 mpq_swap (m_val, from.m_val);
437 return *this;
440 gdb_mpq &operator= (const gdb_mpz &from)
442 mpq_set_z (m_val, from.m_val);
443 return *this;
446 gdb_mpq &operator= (double d)
448 mpq_set_d (m_val, d);
449 return *this;
452 /* Return the sign of this value. This returns -1 for a negative
453 value, 0 if the value is 0, and 1 for a positive value. */
454 int sgn () const
455 { return mpq_sgn (m_val); }
457 gdb_mpq operator+ (const gdb_mpq &other) const
459 gdb_mpq result;
460 mpq_add (result.m_val, m_val, other.m_val);
461 return result;
464 gdb_mpq operator- (const gdb_mpq &other) const
466 gdb_mpq result;
467 mpq_sub (result.m_val, m_val, other.m_val);
468 return result;
471 gdb_mpq operator* (const gdb_mpq &other) const
473 gdb_mpq result;
474 mpq_mul (result.m_val, m_val, other.m_val);
475 return result;
478 gdb_mpq operator/ (const gdb_mpq &other) const
480 gdb_mpq result;
481 mpq_div (result.m_val, m_val, other.m_val);
482 return result;
485 gdb_mpq &operator*= (const gdb_mpq &other)
487 mpq_mul (m_val, m_val, other.m_val);
488 return *this;
491 gdb_mpq &operator/= (const gdb_mpq &other)
493 mpq_div (m_val, m_val, other.m_val);
494 return *this;
497 bool operator== (const gdb_mpq &other) const
499 return mpq_cmp (m_val, other.m_val) == 0;
502 bool operator< (const gdb_mpq &other) const
504 return mpq_cmp (m_val, other.m_val) < 0;
507 /* Return a string representing VAL as "<numerator> / <denominator>". */
508 std::string str () const { return gmp_string_printf ("%Qd", m_val); }
510 /* Return VAL rounded to the nearest integer. */
511 gdb_mpz get_rounded () const;
513 /* Return this value as an integer, rounded toward zero. */
514 gdb_mpz as_integer () const
516 gdb_mpz result;
517 mpz_tdiv_q (result.m_val, mpq_numref (m_val), mpq_denref (m_val));
518 return result;
521 /* Return this value converted to a host double. */
522 double as_double () const
523 { return mpq_get_d (m_val); }
525 /* Set VAL from the contents of the given byte array (BUF), which
526 contains the unscaled value of a fixed point type object.
527 The byte size of the data is the size of BUF.
529 BYTE_ORDER provides the byte_order to use when reading the data.
531 UNSIGNED_P indicates whether the number has an unsigned type.
532 SCALING_FACTOR is the scaling factor to apply after having
533 read the unscaled value from our buffer. */
534 void read_fixed_point (gdb::array_view<const gdb_byte> buf,
535 enum bfd_endian byte_order, bool unsigned_p,
536 const gdb_mpq &scaling_factor);
538 /* Write VAL into BUF as fixed point value following the given BYTE_ORDER.
539 The size of BUF is used as the length to write the value into.
541 UNSIGNED_P indicates whether the number has an unsigned type.
542 SCALING_FACTOR is the scaling factor to apply before writing
543 the unscaled value to our buffer. */
544 void write_fixed_point (gdb::array_view<gdb_byte> buf,
545 enum bfd_endian byte_order, bool unsigned_p,
546 const gdb_mpq &scaling_factor) const;
548 /* The destructor. */
549 ~gdb_mpq () { mpq_clear (m_val); }
551 private:
553 friend struct gdb_mpf;
555 mpq_t m_val;
558 /* A class to make it easier to use GMP's mpf_t values within GDB.
560 Should MPFR become a required dependency, we should probably
561 drop this class in favor of using MPFR. */
563 struct gdb_mpf
565 /* Constructors. */
566 gdb_mpf () { mpf_init (m_val); }
568 DISABLE_COPY_AND_ASSIGN (gdb_mpf);
570 /* Set VAL from the contents of the given buffer (BUF), which
571 contains the unscaled value of a fixed point type object
572 with the given size (LEN) and byte order (BYTE_ORDER).
574 UNSIGNED_P indicates whether the number has an unsigned type.
575 SCALING_FACTOR is the scaling factor to apply after having
576 read the unscaled value from our buffer. */
577 void read_fixed_point (gdb::array_view<const gdb_byte> buf,
578 enum bfd_endian byte_order, bool unsigned_p,
579 const gdb_mpq &scaling_factor)
581 gdb_mpq tmp_q;
583 tmp_q.read_fixed_point (buf, byte_order, unsigned_p, scaling_factor);
584 mpf_set_q (m_val, tmp_q.m_val);
587 /* Convert this value to a string. FMT is the format to use, and
588 should have a single '%' substitution. */
589 std::string str (const char *fmt) const
590 { return gmp_string_printf (fmt, m_val); }
592 /* The destructor. */
593 ~gdb_mpf () { mpf_clear (m_val); }
595 private:
597 mpf_t m_val;
600 /* See declaration above. */
602 template<typename T>
603 void
604 gdb_mpz::set (T src)
606 mpz_import (m_val, 1 /* count */, -1 /* order */,
607 sizeof (T) /* size */, 0 /* endian (0 = native) */,
608 0 /* nails */, &src /* op */);
609 if (std::is_signed<T>::value && src < 0)
611 /* mpz_import does not handle the sign, so our value was imported
612 as an unsigned. Adjust that imported value so as to make it
613 the correct negative value. */
614 gdb_mpz neg_offset;
616 mpz_ui_pow_ui (neg_offset.m_val, 2, sizeof (T) * HOST_CHAR_BIT);
617 mpz_sub (m_val, m_val, neg_offset.m_val);
621 /* See declaration above. */
623 template<typename T>
625 gdb_mpz::as_integer () const
627 T result;
629 this->export_bits ({(gdb_byte *) &result, sizeof (result)},
630 0 /* endian (0 = native) */,
631 !std::is_signed<T>::value /* unsigned_p */,
632 true /* safe */);
634 return result;
637 /* See declaration above. */
639 template<typename T>
641 gdb_mpz::as_integer_truncate () const
643 T result;
645 this->export_bits ({(gdb_byte *) &result, sizeof (result)},
646 0 /* endian (0 = native) */,
647 !std::is_signed<T>::value /* unsigned_p */,
648 false /* safe */);
650 return result;
653 #endif