+
+/* Perform the binary operation indicated by OPCODE, using as operands the
+ target byte streams X and Y, interpreted as floating-point numbers of
+ types TYPE_X and TYPE_Y, respectively. Convert the result to type
+ TYPE_RES and store it into the byte-stream RES.
+
+ The three types must either be all binary floating-point types, or else
+ all decimal floating-point types. Binary and decimal floating-point
+ types cannot be mixed within a single operation. */
+void
+target_float_binop (enum exp_opcode opcode,
+ const gdb_byte *x, const struct type *type_x,
+ const gdb_byte *y, const struct type *type_y,
+ gdb_byte *res, const struct type *type_res)
+{
+ /* Ensure possible padding bytes in the target buffer are zeroed out. */
+ memset (res, 0, TYPE_LENGTH (type_res));
+
+ if (TYPE_CODE (type_res) == TYPE_CODE_FLT)
+ {
+ gdb_assert (TYPE_CODE (type_x) == TYPE_CODE_FLT);
+ gdb_assert (TYPE_CODE (type_y) == TYPE_CODE_FLT);
+ return floatformat_binop (opcode,
+ floatformat_from_type (type_x), x,
+ floatformat_from_type (type_y), y,
+ floatformat_from_type (type_res), res);
+ }
+
+ if (TYPE_CODE (type_res) == TYPE_CODE_DECFLOAT)
+ {
+ gdb_assert (TYPE_CODE (type_x) == TYPE_CODE_DECFLOAT);
+ gdb_assert (TYPE_CODE (type_y) == TYPE_CODE_DECFLOAT);
+ return decimal_binop (opcode,
+ x, TYPE_LENGTH (type_x),
+ gdbarch_byte_order (get_type_arch (type_x)),
+ y, TYPE_LENGTH (type_y),
+ gdbarch_byte_order (get_type_arch (type_y)),
+ res, TYPE_LENGTH (type_res),
+ gdbarch_byte_order (get_type_arch (type_res)));
+ }
+
+ gdb_assert_not_reached ("unexpected type code");
+}
+
+/* Compare the two target byte streams X and Y, interpreted as floating-point
+ numbers of types TYPE_X and TYPE_Y, respectively. Return zero if X and Y
+ are equal, -1 if X is less than Y, and 1 otherwise.
+
+ The two types must either both be binary floating-point types, or else
+ both be decimal floating-point types. Binary and decimal floating-point
+ types cannot compared directly against each other. */
+int
+target_float_compare (const gdb_byte *x, const struct type *type_x,
+ const gdb_byte *y, const struct type *type_y)
+{
+ if (TYPE_CODE (type_x) == TYPE_CODE_FLT)
+ {
+ gdb_assert (TYPE_CODE (type_y) == TYPE_CODE_FLT);
+ return floatformat_compare (floatformat_from_type (type_x), x,
+ floatformat_from_type (type_y), y);
+ }
+
+ if (TYPE_CODE (type_x) == TYPE_CODE_DECFLOAT)
+ {
+ gdb_assert (TYPE_CODE (type_y) == TYPE_CODE_DECFLOAT);
+ return decimal_compare (x, TYPE_LENGTH (type_x),
+ gdbarch_byte_order (get_type_arch (type_x)),
+ y, TYPE_LENGTH (type_y),
+ gdbarch_byte_order (get_type_arch (type_y)));
+ }
+
+ gdb_assert_not_reached ("unexpected type code");
+}
+