/* Simulator Floating-point support.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 2002 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file is part of GDB, the GNU debugger.
typedef struct _sim_fpu {
sim_fpu_class class;
- int normal_exp;
- int result;
int sign;
unsigned64 fraction;
+ int normal_exp;
} sim_fpu;
typedef enum
{
+ sim_fpu_denorm_default = 0,
sim_fpu_denorm_underflow_inexact = 1,
sim_fpu_denorm_zero = 2,
} sim_fpu_denorm;
When converting from the sim_fpu internal type to 32/64 bit packed
format, the operation may result in a loss of precision. The
configuration macro WITH_FPU_CONVERSION controls this. By default,
- silent round to nearest is performed. Alternativly, round up,
+ silent round to nearest is performed. Alternatively, round up,
round down and round to zero can be performed. In a simulator
- emulating exact FPU behavour, sim_fpu_round_{32,64} should be
+ emulating exact FPU behavior, sim_fpu_round_{32,64} should be
called before packing the sim_fpu value. */
INLINE_SIM_FPU (void) sim_fpu_32to (sim_fpu *f, unsigned32 s);
INLINE_SIM_FPU (void) sim_fpu_to232 (unsigned32 *h, unsigned32 *l, const sim_fpu *f);
INLINE_SIM_FPU (void) sim_fpu_to64 (unsigned64 *d, const sim_fpu *f);
-#if WITH_TARGET_FLOATING_POINT_BITSIZE == 32
-#define sim_fpu_tofp sim_fpu_to32
-#define sim_fpu_fpto sim_fpu_32to
-#define sim_fpu_round_fp sim_fpu_round_32
-#endif
-#if WITH_TARGET_FLOATING_POINT_BITSIZE == 64
-#define sim_fpu_tofp sim_fpu_to64
-#define sim_fpu_fpto sim_fpu_64to
-#define sim_fpu_round_fp sim_fpu_round_64
-#endif
+
+/* Create a sim_fpu struct using raw information. (FRACTION & LSMASK
+ (PRECISION-1, 0)) is assumed to contain the fraction part of the
+ floating-point number. The leading bit LSBIT (PRECISION) is always
+ implied. The number created can be represented by:
+
+ (SIGN ? "-" : "+") "1." FRACTION{PRECISION-1,0} X 2 ^ NORMAL_EXP>
+
+ You can not specify zero using this function. */
+
+INLINE_SIM_FPU (void) sim_fpu_fractionto (sim_fpu *f, int sign, int normal_exp, unsigned64 fraction, int precision);
+
+/* Reverse operation. If S is a non-zero number, discards the implied
+ leading one and returns PRECISION fraction bits. No rounding is
+ performed. */
+INLINE_SIM_FPU (unsigned64) sim_fpu_tofraction (const sim_fpu *s, int precision);
+
/* Rounding operators.
-/* Arrithmetic operators.
+/* Arithmetic operators.
FIXME: In the future, additional arguments ROUNDING and BITSIZE may
be added. */
+typedef int (sim_fpu_op1) (sim_fpu *f,
+ const sim_fpu *l);
+typedef int (sim_fpu_op2) (sim_fpu *f,
+ const sim_fpu *l,
+ const sim_fpu *r);
+
INLINE_SIM_FPU (int) sim_fpu_add (sim_fpu *f,
const sim_fpu *l, const sim_fpu *r);
INLINE_SIM_FPU (int) sim_fpu_sub (sim_fpu *f,
const sim_fpu *l, const sim_fpu *r);
INLINE_SIM_FPU (int) sim_fpu_div (sim_fpu *f,
const sim_fpu *l, const sim_fpu *r);
+INLINE_SIM_FPU (int) sim_fpu_max (sim_fpu *f,
+ const sim_fpu *l, const sim_fpu *r);
+INLINE_SIM_FPU (int) sim_fpu_min (sim_fpu *f,
+ const sim_fpu *l, const sim_fpu *r);
INLINE_SIM_FPU (int) sim_fpu_neg (sim_fpu *f,
const sim_fpu *a);
INLINE_SIM_FPU (int) sim_fpu_abs (sim_fpu *f,
sim_fpu_round round);
INLINE_SIM_FPU (int) sim_fpu_u64to (sim_fpu *f, unsigned64 u,
sim_fpu_round round);
+#if 0
INLINE_SIM_FPU (int) sim_fpu_i232to (sim_fpu *f, signed32 h, signed32 l,
sim_fpu_round round);
+#endif
+#if 0
INLINE_SIM_FPU (int) sim_fpu_u232to (sim_fpu *f, unsigned32 h, unsigned32 l,
sim_fpu_round round);
+#endif
INLINE_SIM_FPU (int) sim_fpu_to32i (signed32 *i, const sim_fpu *f,
sim_fpu_round round);
sim_fpu_round round);
INLINE_SIM_FPU (int) sim_fpu_to64u (unsigned64 *u, const sim_fpu *f,
sim_fpu_round round);
+#if 0
INLINE_SIM_FPU (int) sim_fpu_to232i (signed64 *h, signed64 *l, const sim_fpu *f,
sim_fpu_round round);
+#endif
+#if 0
INLINE_SIM_FPU (int) sim_fpu_to232u (unsigned64 *h, unsigned64 *l, const sim_fpu *f,
sim_fpu_round round);
-
+#endif
/* Conversion of internal sim_fpu type to host double format.
- For debuging/tracing only. A SNaN is never returned. */
+ For debugging/tracing only. A SNaN is never returned. */
/* INLINE_SIM_FPU (float) sim_fpu_2f (const sim_fpu *f); */
INLINE_SIM_FPU (double) sim_fpu_2d (const sim_fpu *d);
/* Specific number classes.
- NB: When either a 32/64 bit floating points is converted to
+ NB: When either, a 32/64 bit floating points is converted to
internal format, or an internal format number is rounded to 32/64
bit precision, a special marker is retained that indicates that the
value was normalized. For such numbers both is_number and
- is_denorm will return true. */
+ is_denorm return true. */
INLINE_SIM_FPU (int) sim_fpu_is_nan (const sim_fpu *s); /* 1 => SNaN or QNaN */
INLINE_SIM_FPU (int) sim_fpu_is_snan (const sim_fpu *s); /* 1 => SNaN */
INLINE_SIM_FPU (int) sim_fpu_is_denorm (const sim_fpu *s); /* !zero */
+
+/* Floating point fields */
+
+INLINE_SIM_FPU (int) sim_fpu_sign (const sim_fpu *s);
+INLINE_SIM_FPU (int) sim_fpu_exp (const sim_fpu *s);
+
+
+
/* Specific comparison operators
- The comparison operators set *IS to zero and return a nonzero
- result for NaNs et.al. */
+ For NaNs et.al., the comparison operators will set IS to zero and
+ return a nonzero result. */
INLINE_SIM_FPU (int) sim_fpu_lt (int *is, const sim_fpu *l, const sim_fpu *r);
INLINE_SIM_FPU (int) sim_fpu_le (int *is, const sim_fpu *l, const sim_fpu *r);
#ifndef SIM_FPU_IS_SNAN
enum {
SIM_FPU_IS_SNAN = 1, /* Noisy not-a-number */
- SIM_FPU_IS_QNAN = 2, /* Quite not-a-number */
+ SIM_FPU_IS_QNAN = 2, /* Quiet not-a-number */
SIM_FPU_IS_NINF = 3, /* -infinity */
SIM_FPU_IS_PINF = 4, /* +infinity */
SIM_FPU_IS_NNUMBER = 5, /* -number - [ -MAX .. -MIN ] */
-/* A constant of useful numbers */
+/* A number of useful constants. */
extern const sim_fpu sim_fpu_zero;
extern const sim_fpu sim_fpu_one;
extern const sim_fpu sim_fpu_two;
extern const sim_fpu sim_fpu_qnan;
+extern const sim_fpu sim_fpu_max32;
+extern const sim_fpu sim_fpu_max64;
+
+
+/* Select the applicable functions for the fp_word type */
+
+#if WITH_TARGET_FLOATING_POINT_BITSIZE == 32
+#define sim_fpu_tofp sim_fpu_to32
+#define sim_fpu_fpto sim_fpu_32to
+#define sim_fpu_round_fp sim_fpu_round_32
+#define sim_fpu_maxfp sim_fpu_max32
+#endif
+#if WITH_TARGET_FLOATING_POINT_BITSIZE == 64
+#define sim_fpu_tofp sim_fpu_to64
+#define sim_fpu_fpto sim_fpu_64to
+#define sim_fpu_round_fp sim_fpu_round_64
+#define sim_fpu_maxfp sim_fpu_max64
+#endif
+
/* For debugging */
typedef void sim_fpu_print_func (void *, char *, ...);
+/* Print a sim_fpu with full precision. */
INLINE_SIM_FPU (void) sim_fpu_print_fpu (const sim_fpu *f,
sim_fpu_print_func *print,
void *arg);
+/* Print a sim_fpu with `n' trailing digits. */
+INLINE_SIM_FPU (void) sim_fpu_printn_fpu (const sim_fpu *f,
+ sim_fpu_print_func *print,
+ int digits,
+ void *arg);
+
INLINE_SIM_FPU (void) sim_fpu_print_status (int status,
sim_fpu_print_func *print,
void *arg);
+#if H_REVEALS_MODULE_P (SIM_FPU_INLINE)
+#include "sim-fpu.c"
+#endif
+
#endif