xref: /dflybsd-src/contrib/gdb-7/gdb/dfp.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Decimal floating point support for GDB.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 2007-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "expression.h"
225796c8dcSSimon Schubert #include "gdbtypes.h"
235796c8dcSSimon Schubert #include "value.h"
245796c8dcSSimon Schubert #include "dfp.h"
255796c8dcSSimon Schubert 
265796c8dcSSimon Schubert /* The order of the following headers is important for making sure
275796c8dcSSimon Schubert    decNumber structure is large enough to hold decimal128 digits.  */
285796c8dcSSimon Schubert 
295796c8dcSSimon Schubert #include "dpd/decimal128.h"
305796c8dcSSimon Schubert #include "dpd/decimal64.h"
315796c8dcSSimon Schubert #include "dpd/decimal32.h"
325796c8dcSSimon Schubert 
335796c8dcSSimon Schubert /* In GDB, we are using an array of gdb_byte to represent decimal values.
345796c8dcSSimon Schubert    They are stored in host byte order.  This routine does the conversion if
355796c8dcSSimon Schubert    the target byte order is different.  */
365796c8dcSSimon Schubert static void
match_endianness(const gdb_byte * from,int len,enum bfd_endian byte_order,gdb_byte * to)375796c8dcSSimon Schubert match_endianness (const gdb_byte *from, int len, enum bfd_endian byte_order,
385796c8dcSSimon Schubert 		  gdb_byte *to)
395796c8dcSSimon Schubert {
405796c8dcSSimon Schubert   int i;
415796c8dcSSimon Schubert 
425796c8dcSSimon Schubert #if WORDS_BIGENDIAN
435796c8dcSSimon Schubert #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_LITTLE
445796c8dcSSimon Schubert #else
455796c8dcSSimon Schubert #define OPPOSITE_BYTE_ORDER BFD_ENDIAN_BIG
465796c8dcSSimon Schubert #endif
475796c8dcSSimon Schubert 
485796c8dcSSimon Schubert   if (byte_order == OPPOSITE_BYTE_ORDER)
495796c8dcSSimon Schubert     for (i = 0; i < len; i++)
505796c8dcSSimon Schubert       to[i] = from[len - i - 1];
515796c8dcSSimon Schubert   else
525796c8dcSSimon Schubert     for (i = 0; i < len; i++)
535796c8dcSSimon Schubert       to[i] = from[i];
545796c8dcSSimon Schubert 
555796c8dcSSimon Schubert   return;
565796c8dcSSimon Schubert }
575796c8dcSSimon Schubert 
585796c8dcSSimon Schubert /* Helper function to get the appropriate libdecnumber context for each size
595796c8dcSSimon Schubert    of decimal float.  */
605796c8dcSSimon Schubert static void
set_decnumber_context(decContext * ctx,int len)615796c8dcSSimon Schubert set_decnumber_context (decContext *ctx, int len)
625796c8dcSSimon Schubert {
635796c8dcSSimon Schubert   switch (len)
645796c8dcSSimon Schubert     {
655796c8dcSSimon Schubert       case 4:
665796c8dcSSimon Schubert 	decContextDefault (ctx, DEC_INIT_DECIMAL32);
675796c8dcSSimon Schubert 	break;
685796c8dcSSimon Schubert       case 8:
695796c8dcSSimon Schubert 	decContextDefault (ctx, DEC_INIT_DECIMAL64);
705796c8dcSSimon Schubert 	break;
715796c8dcSSimon Schubert       case 16:
725796c8dcSSimon Schubert 	decContextDefault (ctx, DEC_INIT_DECIMAL128);
735796c8dcSSimon Schubert 	break;
745796c8dcSSimon Schubert     }
755796c8dcSSimon Schubert 
765796c8dcSSimon Schubert   ctx->traps = 0;
775796c8dcSSimon Schubert }
785796c8dcSSimon Schubert 
795796c8dcSSimon Schubert /* Check for errors signaled in the decimal context structure.  */
805796c8dcSSimon Schubert static void
decimal_check_errors(decContext * ctx)815796c8dcSSimon Schubert decimal_check_errors (decContext *ctx)
825796c8dcSSimon Schubert {
835796c8dcSSimon Schubert   /* An error here could be a division by zero, an overflow, an underflow or
845796c8dcSSimon Schubert      an invalid operation (from the DEC_Errors constant in decContext.h).
855796c8dcSSimon Schubert      Since GDB doesn't complain about division by zero, overflow or underflow
865796c8dcSSimon Schubert      errors for binary floating, we won't complain about them for decimal
875796c8dcSSimon Schubert      floating either.  */
885796c8dcSSimon Schubert   if (ctx->status & DEC_IEEE_854_Invalid_operation)
895796c8dcSSimon Schubert     {
905796c8dcSSimon Schubert       /* Leave only the error bits in the status flags.  */
915796c8dcSSimon Schubert       ctx->status &= DEC_IEEE_854_Invalid_operation;
92c50c785cSJohn Marino       error (_("Cannot perform operation: %s"),
93c50c785cSJohn Marino 	     decContextStatusToString (ctx));
945796c8dcSSimon Schubert     }
955796c8dcSSimon Schubert }
965796c8dcSSimon Schubert 
975796c8dcSSimon Schubert /* Helper function to convert from libdecnumber's appropriate representation
985796c8dcSSimon Schubert    for computation to each size of decimal float.  */
995796c8dcSSimon Schubert static void
decimal_from_number(const decNumber * from,gdb_byte * to,int len)1005796c8dcSSimon Schubert decimal_from_number (const decNumber *from, gdb_byte *to, int len)
1015796c8dcSSimon Schubert {
1025796c8dcSSimon Schubert   decContext set;
1035796c8dcSSimon Schubert 
1045796c8dcSSimon Schubert   set_decnumber_context (&set, len);
1055796c8dcSSimon Schubert 
1065796c8dcSSimon Schubert   switch (len)
1075796c8dcSSimon Schubert     {
1085796c8dcSSimon Schubert       case 4:
1095796c8dcSSimon Schubert 	decimal32FromNumber ((decimal32 *) to, from, &set);
1105796c8dcSSimon Schubert 	break;
1115796c8dcSSimon Schubert       case 8:
1125796c8dcSSimon Schubert 	decimal64FromNumber ((decimal64 *) to, from, &set);
1135796c8dcSSimon Schubert 	break;
1145796c8dcSSimon Schubert       case 16:
1155796c8dcSSimon Schubert 	decimal128FromNumber ((decimal128 *) to, from, &set);
1165796c8dcSSimon Schubert 	break;
1175796c8dcSSimon Schubert     }
1185796c8dcSSimon Schubert }
1195796c8dcSSimon Schubert 
1205796c8dcSSimon Schubert /* Helper function to convert each size of decimal float to libdecnumber's
1215796c8dcSSimon Schubert    appropriate representation for computation.  */
1225796c8dcSSimon Schubert static void
decimal_to_number(const gdb_byte * from,int len,decNumber * to)1235796c8dcSSimon Schubert decimal_to_number (const gdb_byte *from, int len, decNumber *to)
1245796c8dcSSimon Schubert {
1255796c8dcSSimon Schubert   switch (len)
1265796c8dcSSimon Schubert     {
1275796c8dcSSimon Schubert       case 4:
1285796c8dcSSimon Schubert 	decimal32ToNumber ((decimal32 *) from, to);
1295796c8dcSSimon Schubert 	break;
1305796c8dcSSimon Schubert       case 8:
1315796c8dcSSimon Schubert 	decimal64ToNumber ((decimal64 *) from, to);
1325796c8dcSSimon Schubert 	break;
1335796c8dcSSimon Schubert       case 16:
1345796c8dcSSimon Schubert 	decimal128ToNumber ((decimal128 *) from, to);
1355796c8dcSSimon Schubert 	break;
1365796c8dcSSimon Schubert       default:
137c50c785cSJohn Marino 	error (_("Unknown decimal floating point type."));
1385796c8dcSSimon Schubert 	break;
1395796c8dcSSimon Schubert     }
1405796c8dcSSimon Schubert }
1415796c8dcSSimon Schubert 
1425796c8dcSSimon Schubert /* Convert decimal type to its string representation.  LEN is the length
1435796c8dcSSimon Schubert    of the decimal type, 4 bytes for decimal32, 8 bytes for decimal64 and
1445796c8dcSSimon Schubert    16 bytes for decimal128.  */
1455796c8dcSSimon Schubert void
decimal_to_string(const gdb_byte * decbytes,int len,enum bfd_endian byte_order,char * s)1465796c8dcSSimon Schubert decimal_to_string (const gdb_byte *decbytes, int len,
1475796c8dcSSimon Schubert 		   enum bfd_endian byte_order, char *s)
1485796c8dcSSimon Schubert {
1495796c8dcSSimon Schubert   gdb_byte dec[16];
1505796c8dcSSimon Schubert 
1515796c8dcSSimon Schubert   match_endianness (decbytes, len, byte_order, dec);
1525796c8dcSSimon Schubert 
1535796c8dcSSimon Schubert   switch (len)
1545796c8dcSSimon Schubert     {
1555796c8dcSSimon Schubert       case 4:
1565796c8dcSSimon Schubert 	decimal32ToString ((decimal32 *) dec, s);
1575796c8dcSSimon Schubert 	break;
1585796c8dcSSimon Schubert       case 8:
1595796c8dcSSimon Schubert 	decimal64ToString ((decimal64 *) dec, s);
1605796c8dcSSimon Schubert 	break;
1615796c8dcSSimon Schubert       case 16:
1625796c8dcSSimon Schubert 	decimal128ToString ((decimal128 *) dec, s);
1635796c8dcSSimon Schubert 	break;
1645796c8dcSSimon Schubert       default:
1655796c8dcSSimon Schubert 	error (_("Unknown decimal floating point type."));
1665796c8dcSSimon Schubert 	break;
1675796c8dcSSimon Schubert     }
1685796c8dcSSimon Schubert }
1695796c8dcSSimon Schubert 
1705796c8dcSSimon Schubert /* Convert the string form of a decimal value to its decimal representation.
1715796c8dcSSimon Schubert    LEN is the length of the decimal type, 4 bytes for decimal32, 8 bytes for
1725796c8dcSSimon Schubert    decimal64 and 16 bytes for decimal128.  */
1735796c8dcSSimon Schubert int
decimal_from_string(gdb_byte * decbytes,int len,enum bfd_endian byte_order,const char * string)1745796c8dcSSimon Schubert decimal_from_string (gdb_byte *decbytes, int len, enum bfd_endian byte_order,
1755796c8dcSSimon Schubert 		     const char *string)
1765796c8dcSSimon Schubert {
1775796c8dcSSimon Schubert   decContext set;
1785796c8dcSSimon Schubert   gdb_byte dec[16];
1795796c8dcSSimon Schubert 
1805796c8dcSSimon Schubert   set_decnumber_context (&set, len);
1815796c8dcSSimon Schubert 
1825796c8dcSSimon Schubert   switch (len)
1835796c8dcSSimon Schubert     {
1845796c8dcSSimon Schubert       case 4:
1855796c8dcSSimon Schubert 	decimal32FromString ((decimal32 *) dec, string, &set);
1865796c8dcSSimon Schubert 	break;
1875796c8dcSSimon Schubert       case 8:
1885796c8dcSSimon Schubert 	decimal64FromString ((decimal64 *) dec, string, &set);
1895796c8dcSSimon Schubert 	break;
1905796c8dcSSimon Schubert       case 16:
1915796c8dcSSimon Schubert 	decimal128FromString ((decimal128 *) dec, string, &set);
1925796c8dcSSimon Schubert 	break;
1935796c8dcSSimon Schubert       default:
1945796c8dcSSimon Schubert 	error (_("Unknown decimal floating point type."));
1955796c8dcSSimon Schubert 	break;
1965796c8dcSSimon Schubert     }
1975796c8dcSSimon Schubert 
1985796c8dcSSimon Schubert   match_endianness (dec, len, byte_order, decbytes);
1995796c8dcSSimon Schubert 
2005796c8dcSSimon Schubert   /* Check for errors in the DFP operation.  */
2015796c8dcSSimon Schubert   decimal_check_errors (&set);
2025796c8dcSSimon Schubert 
2035796c8dcSSimon Schubert   return 1;
2045796c8dcSSimon Schubert }
2055796c8dcSSimon Schubert 
2065796c8dcSSimon Schubert /* Converts a value of an integral type to a decimal float of
2075796c8dcSSimon Schubert    specified LEN bytes.  */
2085796c8dcSSimon Schubert void
decimal_from_integral(struct value * from,gdb_byte * to,int len,enum bfd_endian byte_order)2095796c8dcSSimon Schubert decimal_from_integral (struct value *from,
2105796c8dcSSimon Schubert 		       gdb_byte *to, int len, enum bfd_endian byte_order)
2115796c8dcSSimon Schubert {
2125796c8dcSSimon Schubert   LONGEST l;
2135796c8dcSSimon Schubert   gdb_byte dec[16];
2145796c8dcSSimon Schubert   decNumber number;
2155796c8dcSSimon Schubert   struct type *type;
2165796c8dcSSimon Schubert 
2175796c8dcSSimon Schubert   type = check_typedef (value_type (from));
2185796c8dcSSimon Schubert 
2195796c8dcSSimon Schubert   if (TYPE_LENGTH (type) > 4)
2205796c8dcSSimon Schubert     /* libdecnumber can convert only 32-bit integers.  */
221c50c785cSJohn Marino     error (_("Conversion of large integer to a "
222c50c785cSJohn Marino 	     "decimal floating type is not supported."));
2235796c8dcSSimon Schubert 
2245796c8dcSSimon Schubert   l = value_as_long (from);
2255796c8dcSSimon Schubert 
2265796c8dcSSimon Schubert   if (TYPE_UNSIGNED (type))
2275796c8dcSSimon Schubert     decNumberFromUInt32 (&number, (unsigned int) l);
2285796c8dcSSimon Schubert   else
2295796c8dcSSimon Schubert     decNumberFromInt32 (&number, (int) l);
2305796c8dcSSimon Schubert 
2315796c8dcSSimon Schubert   decimal_from_number (&number, dec, len);
2325796c8dcSSimon Schubert   match_endianness (dec, len, byte_order, to);
2335796c8dcSSimon Schubert }
2345796c8dcSSimon Schubert 
2355796c8dcSSimon Schubert /* Converts a value of a float type to a decimal float of
2365796c8dcSSimon Schubert    specified LEN bytes.
2375796c8dcSSimon Schubert 
2385796c8dcSSimon Schubert    This is an ugly way to do the conversion, but libdecnumber does
2395796c8dcSSimon Schubert    not offer a direct way to do it.  */
2405796c8dcSSimon Schubert void
decimal_from_floating(struct value * from,gdb_byte * to,int len,enum bfd_endian byte_order)2415796c8dcSSimon Schubert decimal_from_floating (struct value *from,
2425796c8dcSSimon Schubert 		       gdb_byte *to, int len, enum bfd_endian byte_order)
2435796c8dcSSimon Schubert {
2445796c8dcSSimon Schubert   char *buffer;
2455796c8dcSSimon Schubert 
2465796c8dcSSimon Schubert   buffer = xstrprintf ("%.30" DOUBLEST_PRINT_FORMAT, value_as_double (from));
2475796c8dcSSimon Schubert 
2485796c8dcSSimon Schubert   decimal_from_string (to, len, byte_order, buffer);
2495796c8dcSSimon Schubert 
2505796c8dcSSimon Schubert   xfree (buffer);
2515796c8dcSSimon Schubert }
2525796c8dcSSimon Schubert 
2535796c8dcSSimon Schubert /* Converts a decimal float of LEN bytes to a double value.  */
2545796c8dcSSimon Schubert DOUBLEST
decimal_to_doublest(const gdb_byte * from,int len,enum bfd_endian byte_order)2555796c8dcSSimon Schubert decimal_to_doublest (const gdb_byte *from, int len, enum bfd_endian byte_order)
2565796c8dcSSimon Schubert {
2575796c8dcSSimon Schubert   char buffer[MAX_DECIMAL_STRING];
2585796c8dcSSimon Schubert 
2595796c8dcSSimon Schubert   /* This is an ugly way to do the conversion, but libdecnumber does
2605796c8dcSSimon Schubert      not offer a direct way to do it.  */
2615796c8dcSSimon Schubert   decimal_to_string (from, len, byte_order, buffer);
2625796c8dcSSimon Schubert   return strtod (buffer, NULL);
2635796c8dcSSimon Schubert }
2645796c8dcSSimon Schubert 
2655796c8dcSSimon Schubert /* Perform operation OP with operands X and Y with sizes LEN_X and LEN_Y
2665796c8dcSSimon Schubert    and byte orders BYTE_ORDER_X and BYTE_ORDER_Y, and store value in
2675796c8dcSSimon Schubert    RESULT with size LEN_RESULT and byte order BYTE_ORDER_RESULT.  */
2685796c8dcSSimon Schubert void
decimal_binop(enum exp_opcode op,const gdb_byte * x,int len_x,enum bfd_endian byte_order_x,const gdb_byte * y,int len_y,enum bfd_endian byte_order_y,gdb_byte * result,int len_result,enum bfd_endian byte_order_result)2695796c8dcSSimon Schubert decimal_binop (enum exp_opcode op,
2705796c8dcSSimon Schubert 	       const gdb_byte *x, int len_x, enum bfd_endian byte_order_x,
2715796c8dcSSimon Schubert 	       const gdb_byte *y, int len_y, enum bfd_endian byte_order_y,
2725796c8dcSSimon Schubert 	       gdb_byte *result, int len_result,
2735796c8dcSSimon Schubert 	       enum bfd_endian byte_order_result)
2745796c8dcSSimon Schubert {
2755796c8dcSSimon Schubert   decContext set;
2765796c8dcSSimon Schubert   decNumber number1, number2, number3;
2775796c8dcSSimon Schubert   gdb_byte dec1[16], dec2[16], dec3[16];
2785796c8dcSSimon Schubert 
2795796c8dcSSimon Schubert   match_endianness (x, len_x, byte_order_x, dec1);
2805796c8dcSSimon Schubert   match_endianness (y, len_y, byte_order_y, dec2);
2815796c8dcSSimon Schubert 
2825796c8dcSSimon Schubert   decimal_to_number (dec1, len_x, &number1);
2835796c8dcSSimon Schubert   decimal_to_number (dec2, len_y, &number2);
2845796c8dcSSimon Schubert 
2855796c8dcSSimon Schubert   set_decnumber_context (&set, len_result);
2865796c8dcSSimon Schubert 
2875796c8dcSSimon Schubert   switch (op)
2885796c8dcSSimon Schubert     {
2895796c8dcSSimon Schubert       case BINOP_ADD:
2905796c8dcSSimon Schubert 	decNumberAdd (&number3, &number1, &number2, &set);
2915796c8dcSSimon Schubert 	break;
2925796c8dcSSimon Schubert       case BINOP_SUB:
2935796c8dcSSimon Schubert 	decNumberSubtract (&number3, &number1, &number2, &set);
2945796c8dcSSimon Schubert 	break;
2955796c8dcSSimon Schubert       case BINOP_MUL:
2965796c8dcSSimon Schubert 	decNumberMultiply (&number3, &number1, &number2, &set);
2975796c8dcSSimon Schubert 	break;
2985796c8dcSSimon Schubert       case BINOP_DIV:
2995796c8dcSSimon Schubert 	decNumberDivide (&number3, &number1, &number2, &set);
3005796c8dcSSimon Schubert 	break;
3015796c8dcSSimon Schubert       case BINOP_EXP:
3025796c8dcSSimon Schubert 	decNumberPower (&number3, &number1, &number2, &set);
3035796c8dcSSimon Schubert 	break;
3045796c8dcSSimon Schubert       default:
3055796c8dcSSimon Schubert 	internal_error (__FILE__, __LINE__,
3065796c8dcSSimon Schubert 			_("Unknown decimal floating point operation."));
3075796c8dcSSimon Schubert 	break;
3085796c8dcSSimon Schubert     }
3095796c8dcSSimon Schubert 
3105796c8dcSSimon Schubert   /* Check for errors in the DFP operation.  */
3115796c8dcSSimon Schubert   decimal_check_errors (&set);
3125796c8dcSSimon Schubert 
3135796c8dcSSimon Schubert   decimal_from_number (&number3, dec3, len_result);
3145796c8dcSSimon Schubert 
3155796c8dcSSimon Schubert   match_endianness (dec3, len_result, byte_order_result, result);
3165796c8dcSSimon Schubert }
3175796c8dcSSimon Schubert 
3185796c8dcSSimon Schubert /* Returns true if X (which is LEN bytes wide) is the number zero.  */
3195796c8dcSSimon Schubert int
decimal_is_zero(const gdb_byte * x,int len,enum bfd_endian byte_order)3205796c8dcSSimon Schubert decimal_is_zero (const gdb_byte *x, int len, enum bfd_endian byte_order)
3215796c8dcSSimon Schubert {
3225796c8dcSSimon Schubert   decNumber number;
3235796c8dcSSimon Schubert   gdb_byte dec[16];
3245796c8dcSSimon Schubert 
3255796c8dcSSimon Schubert   match_endianness (x, len, byte_order, dec);
3265796c8dcSSimon Schubert   decimal_to_number (dec, len, &number);
3275796c8dcSSimon Schubert 
3285796c8dcSSimon Schubert   return decNumberIsZero (&number);
3295796c8dcSSimon Schubert }
3305796c8dcSSimon Schubert 
3315796c8dcSSimon Schubert /* Compares two numbers numerically.  If X is less than Y then the return value
3325796c8dcSSimon Schubert    will be -1.  If they are equal, then the return value will be 0.  If X is
3335796c8dcSSimon Schubert    greater than the Y then the return value will be 1.  */
3345796c8dcSSimon Schubert int
decimal_compare(const gdb_byte * x,int len_x,enum bfd_endian byte_order_x,const gdb_byte * y,int len_y,enum bfd_endian byte_order_y)3355796c8dcSSimon Schubert decimal_compare (const gdb_byte *x, int len_x, enum bfd_endian byte_order_x,
3365796c8dcSSimon Schubert 		 const gdb_byte *y, int len_y, enum bfd_endian byte_order_y)
3375796c8dcSSimon Schubert {
3385796c8dcSSimon Schubert   decNumber number1, number2, result;
3395796c8dcSSimon Schubert   decContext set;
3405796c8dcSSimon Schubert   gdb_byte dec1[16], dec2[16];
3415796c8dcSSimon Schubert   int len_result;
3425796c8dcSSimon Schubert 
3435796c8dcSSimon Schubert   match_endianness (x, len_x, byte_order_x, dec1);
3445796c8dcSSimon Schubert   match_endianness (y, len_y, byte_order_y, dec2);
3455796c8dcSSimon Schubert 
3465796c8dcSSimon Schubert   decimal_to_number (dec1, len_x, &number1);
3475796c8dcSSimon Schubert   decimal_to_number (dec2, len_y, &number2);
3485796c8dcSSimon Schubert 
3495796c8dcSSimon Schubert   /* Perform the comparison in the larger of the two sizes.  */
3505796c8dcSSimon Schubert   len_result = len_x > len_y ? len_x : len_y;
3515796c8dcSSimon Schubert   set_decnumber_context (&set, len_result);
3525796c8dcSSimon Schubert 
3535796c8dcSSimon Schubert   decNumberCompare (&result, &number1, &number2, &set);
3545796c8dcSSimon Schubert 
3555796c8dcSSimon Schubert   /* Check for errors in the DFP operation.  */
3565796c8dcSSimon Schubert   decimal_check_errors (&set);
3575796c8dcSSimon Schubert 
3585796c8dcSSimon Schubert   if (decNumberIsNaN (&result))
3595796c8dcSSimon Schubert     error (_("Comparison with an invalid number (NaN)."));
3605796c8dcSSimon Schubert   else if (decNumberIsZero (&result))
3615796c8dcSSimon Schubert     return 0;
3625796c8dcSSimon Schubert   else if (decNumberIsNegative (&result))
3635796c8dcSSimon Schubert     return -1;
3645796c8dcSSimon Schubert   else
3655796c8dcSSimon Schubert     return 1;
3665796c8dcSSimon Schubert }
3675796c8dcSSimon Schubert 
3685796c8dcSSimon Schubert /* Convert a decimal value from a decimal type with LEN_FROM bytes to a
3695796c8dcSSimon Schubert    decimal type with LEN_TO bytes.  */
3705796c8dcSSimon Schubert void
decimal_convert(const gdb_byte * from,int len_from,enum bfd_endian byte_order_from,gdb_byte * to,int len_to,enum bfd_endian byte_order_to)3715796c8dcSSimon Schubert decimal_convert (const gdb_byte *from, int len_from,
3725796c8dcSSimon Schubert 		 enum bfd_endian byte_order_from, gdb_byte *to, int len_to,
3735796c8dcSSimon Schubert 		 enum bfd_endian byte_order_to)
3745796c8dcSSimon Schubert {
3755796c8dcSSimon Schubert   decNumber number;
3765796c8dcSSimon Schubert   gdb_byte dec[16];
3775796c8dcSSimon Schubert 
3785796c8dcSSimon Schubert   match_endianness (from, len_from, byte_order_from, dec);
3795796c8dcSSimon Schubert 
3805796c8dcSSimon Schubert   decimal_to_number (dec, len_from, &number);
3815796c8dcSSimon Schubert   decimal_from_number (&number, dec, len_to);
3825796c8dcSSimon Schubert 
3835796c8dcSSimon Schubert   match_endianness (dec, len_to, byte_order_to, to);
3845796c8dcSSimon Schubert }
385