1193323Sed/* Simulator Floating-point support. 2193323Sed 3193323Sed Copyright 1997-2023 Free Software Foundation, Inc. 4193323Sed 5193323Sed Contributed by Cygnus Support. 6193323Sed 7193323SedThis file is part of GDB, the GNU debugger. 8193323Sed 9193323SedThis program is free software; you can redistribute it and/or modify 10193323Sedit under the terms of the GNU General Public License as published by 11193323Sedthe Free Software Foundation; either version 3 of the License, or 12193323Sed(at your option) any later version. 13193323Sed 14193323SedThis program is distributed in the hope that it will be useful, 15193323Sedbut WITHOUT ANY WARRANTY; without even the implied warranty of 16193323SedMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17193323SedGNU General Public License for more details. 18193323Sed 19193323SedYou should have received a copy of the GNU General Public License 20193323Sedalong with this program. If not, see <http://www.gnu.org/licenses/>. */ 21239462Sdim 22239462Sdim 23239462Sdim 24193323Sed#ifndef SIM_FPU_H 25193323Sed#define SIM_FPU_H 26193323Sed 27204961Srdivacky 28193323Sed#include <stdbool.h> 29193323Sed 30193323Sed 31193323Sed/* The FPU intermediate type - this object, passed by reference, 32193323Sed should be treated as opaque. 33193323Sed 34193323Sed 35193323Sed Pragmatics - pass struct by ref: 36193323Sed 37193323Sed The alternatives for this object/interface that were considered 38193323Sed were: a packed 64 bit value; an unpacked structure passed by value; 39193323Sed and an unpacked structure passed by reference. 40198090Srdivacky 41198090Srdivacky The packed 64 bit value was rejected because: it limited the 42198090Srdivacky precision of intermediate values; reasonable performance would only 43198090Srdivacky be achieved when the sim_fpu package was in-lined allowing repeated 44210299Sed unpacking operations to be eliminated. 45210299Sed 46210299Sed For unpacked structures (passed by value and reference), the code 47210299Sed quality of GCC-2.7 (on x86) for each alternative was compared. 48210299Sed Needless to say the results, while better than for a packed 64 bit 49210299Sed object, were still poor (GCC had only limited support for the 50212904Sdim optimization of references to structure members). Regardless, the 51212904Sdim struct-by-ref alternative achieved better results when compiled 52212904Sdim with (better speed) and without (better code density) in-lining. 53212904Sdim Here's looking forward to an improved GCC optimizer. 54193323Sed 55193323Sed 56193323Sed Pragmatics - avoid host FP hardware: 57193323Sed 58193323Sed FP operations can be implemented by either: the host's floating 59193323Sed point hardware; or by emulating the FP operations using integer 60203954Srdivacky only routines. This is direct tradeoff between speed, portability 61203954Srdivacky and correctness. 62208599Srdivacky 63193323Sed The two principal reasons for selecting portability and correctness 64218893Sdim over speed are: 65218893Sdim 66224145Sdim 1 - Correctness. The assumption that FP correctness wasn't an 67224145Sdim issue for code being run on simulators was wrong. Instead of 68224145Sdim running FP tolerant (?) code, simulator users instead typically run 69210299Sed very aggressive FP code sequences. The sole purpose of those 70210299Sed sequences being to test the target ISA's FP implementation. 71212904Sdim 72212904Sdim 2 - Portability. The host FP implementation is not predictable. A 73212904Sdim simulator modeling aggressive FP code sequences using the hosts FPU 74226633Sdim relies heavily on the correctness of the hosts FP implementation. 75226633Sdim It turns out that such trust can be misplaced. The behavior of 76226633Sdim host FP implementations when handling edge conditions such as SNaNs 77226633Sdim and exceptions varied widely. 78226633Sdim 79226633Sdim 80226633Sdim */ 81226633Sdim 82226633Sdim 83226633Sdimtypedef enum 84226633Sdim{ 85226633Sdim sim_fpu_class_zero, 86243830Sdim sim_fpu_class_snan, 87243830Sdim sim_fpu_class_qnan, 88243830Sdim sim_fpu_class_number, 89243830Sdim sim_fpu_class_denorm, 90243830Sdim sim_fpu_class_infinity, 91243830Sdim} sim_fpu_class; 92243830Sdim 93193323Sedtypedef struct _sim_fpu { 94193323Sed sim_fpu_class class; 95218893Sdim int sign; 96218893Sdim uint64_t fraction; 97193323Sed int normal_exp; 98193323Sed} sim_fpu; 99193323Sed 100243830Sdim 101193323Sed 102243830Sdim/* Rounding options. 103243830Sdim 104239462Sdim The value zero (sim_fpu_round_default) for ALU operations indicates 105239462Sdim that, when possible, rounding should be avoided. */ 106239462Sdim 107239462Sdimtypedef enum 108193323Sed{ 109193323Sed sim_fpu_round_default = 0, 110218893Sdim sim_fpu_round_near = 1, 111205407Srdivacky sim_fpu_round_zero = 2, 112193323Sed sim_fpu_round_up = 3, 113218893Sdim sim_fpu_round_down = 4, 114205407Srdivacky} sim_fpu_round; 115193323Sed 116218893Sdim 117205407Srdivacky/* Options when handling denormalized numbers. */ 118193323Sed 119193323Sedtypedef enum 120249423Sdim{ 121193323Sed sim_fpu_denorm_default = 0, 122193323Sed sim_fpu_denorm_underflow_inexact = 1, 123218893Sdim sim_fpu_denorm_zero = 2, 124193323Sed} sim_fpu_denorm; 125193323Sed 126218893Sdim 127193323Sed 128193323Sed/* Status values returned by FPU operators. 129193323Sed 130198090Srdivacky When checking the result of an FP sequence (ex 32to, add, single, 131198090Srdivacky to32) the caller may either: check the return value of each FP 132193323Sed operator; or form the union (OR) of the returned values and examine 133210299Sed them once at the end. 134210299Sed 135210299Sed FIXME: This facility is still being developed. The choice of 136193323Sed status values returned and their exact meaning may changed in the 137218893Sdim future. */ 138193323Sed 139239462Sdimtypedef enum 140239462Sdim{ 141239462Sdim sim_fpu_status_invalid_snan = 1, 142195340Sed sim_fpu_status_invalid_qnan = 2, 143218893Sdim sim_fpu_status_invalid_isi = 4, /* (inf - inf) */ 144193323Sed sim_fpu_status_invalid_idi = 8, /* (inf / inf) */ 145193323Sed sim_fpu_status_invalid_zdz = 16, /* (0 / 0) */ 146193323Sed sim_fpu_status_invalid_imz = 32, /* (inf * 0) */ 147218893Sdim sim_fpu_status_invalid_cvi = 64, /* convert to integer */ 148218893Sdim sim_fpu_status_invalid_div0 = 128, /* (X / 0) */ 149218893Sdim sim_fpu_status_invalid_cmp = 256, /* compare */ 150193323Sed sim_fpu_status_invalid_sqrt = 512, 151226633Sdim sim_fpu_status_invalid_irx = 1024, /* (inf % X) */ 152226633Sdim sim_fpu_status_rounded = 2048, 153226633Sdim sim_fpu_status_inexact = 4096, 154226633Sdim sim_fpu_status_overflow = 8192, 155226633Sdim sim_fpu_status_underflow = 16384, 156226633Sdim sim_fpu_status_denorm = 32768, 157193323Sed} sim_fpu_status; 158208599Srdivacky 159243830Sdim 160243830Sdim 161208599Srdivacky 162243830Sdim/* State used by the FPU. 163243830Sdim 164193323Sed FIXME: This state is global, but should be moved to SIM_CPU. */ 165212904Sdim 166243830Sdimtypedef enum 167218893Sdim{ 168243830Sdim sim_fpu_ieee754_1985, 169224145Sdim sim_fpu_ieee754_2008, 170218893Sdim} sim_fpu_mode; 171200581Srdivacky 172202878Srdivackytypedef struct _sim_fpu_state { 173202878Srdivacky bool quiet_nan_inverted; /* Toggle quiet NaN semantics. */ 174218893Sdim sim_fpu_mode current_mode; 175218893Sdim} sim_fpu_state; 176210299Sed 177212904Sdim 178212904Sdim 179212904Sdim 180193323Sed/* Directly map between a 32/64 bit register and the sim_fpu internal 181193323Sed type. 182193323Sed 183224145Sdim When converting from the 32/64 bit packed format to the sim_fpu 184239462Sdim internal type, the operation is exact. 185212904Sdim 186212904Sdim When converting from the sim_fpu internal type to 32/64 bit packed 187224145Sdim format, the operation may result in a loss of precision. The 188239462Sdim configuration macro WITH_FPU_CONVERSION controls this. By default, 189224145Sdim silent round to nearest is performed. Alternatively, round up, 190239462Sdim round down and round to zero can be performed. In a simulator 191218893Sdim emulating exact FPU behavior, sim_fpu_round_{32,64} should be 192224145Sdim called before packing the sim_fpu value. */ 193239462Sdim 194212904SdimINLINE_SIM_FPU (void) sim_fpu_32to (sim_fpu *f, uint32_t s); 195224145SdimINLINE_SIM_FPU (void) sim_fpu_232to (sim_fpu *f, uint32_t h, uint32_t l); 196239462SdimINLINE_SIM_FPU (void) sim_fpu_64to (sim_fpu *f, uint64_t d); 197212904Sdim 198224145SdimINLINE_SIM_FPU (void) sim_fpu_to32 (uint32_t *s, const sim_fpu *f); 199239462SdimINLINE_SIM_FPU (void) sim_fpu_to232 (uint32_t *h, uint32_t *l, const sim_fpu *f); 200224145SdimINLINE_SIM_FPU (void) sim_fpu_to64 (uint64_t *d, const sim_fpu *f); 201239462Sdim 202234353Sdim 203239462Sdim/* Create a sim_fpu struct using raw information. (FRACTION & LSMASK 204224145Sdim (PRECISION-1, 0)) is assumed to contain the fraction part of the 205239462Sdim floating-point number. The leading bit LSBIT (PRECISION) is always 206224145Sdim implied. The number created can be represented by: 207239462Sdim 208224145Sdim (SIGN ? "-" : "+") "1." FRACTION{PRECISION-1,0} X 2 ^ NORMAL_EXP> 209239462Sdim 210243830Sdim You can not specify zero using this function. */ 211243830Sdim 212218893SdimINLINE_SIM_FPU (void) sim_fpu_fractionto (sim_fpu *f, int sign, int normal_exp, uint64_t fraction, int precision); 213239462Sdim 214239462Sdim/* Reverse operation. If S is a non-zero number, discards the implied 215224145Sdim leading one and returns PRECISION fraction bits. No rounding is 216239462Sdim performed. */ 217239462SdimINLINE_SIM_FPU (uint64_t) sim_fpu_tofraction (const sim_fpu *s, int precision); 218218893Sdim 219239462Sdim 220239462Sdim 221218893Sdim/* Rounding operators. 222239462Sdim 223239462Sdim Force an intermediate result to an exact 32/64 bit 224251662Sdim representation. */ 225251662Sdim 226251662SdimINLINE_SIM_FPU (int) sim_fpu_round_32 (sim_fpu *f, 227212904Sdim sim_fpu_round round, 228198090Srdivacky sim_fpu_denorm denorm); 229224145SdimINLINE_SIM_FPU (int) sim_fpu_round_64 (sim_fpu *f, 230239462Sdim sim_fpu_round round, 231212904Sdim sim_fpu_denorm denorm); 232224145Sdim 233239462Sdim 234239462Sdim 235226633Sdim/* Arithmetic operators. 236239462Sdim 237226633Sdim FIXME: In the future, additional arguments ROUNDING and BITSIZE may 238239462Sdim be added. */ 239239462Sdim 240224145Sdimtypedef int (sim_fpu_op1) (sim_fpu *f, 241239462Sdim const sim_fpu *l); 242234353Sdimtypedef int (sim_fpu_op2) (sim_fpu *f, 243234353Sdim const sim_fpu *l, 244234353Sdim const sim_fpu *r); 245249423Sdim 246249423SdimINLINE_SIM_FPU (int) sim_fpu_add (sim_fpu *f, 247249423Sdim const sim_fpu *l, const sim_fpu *r); 248193323SedINLINE_SIM_FPU (int) sim_fpu_sub (sim_fpu *f, 249199989Srdivacky const sim_fpu *l, const sim_fpu *r); 250212904SdimINLINE_SIM_FPU (int) sim_fpu_mul (sim_fpu *f, 251212904Sdim const sim_fpu *l, const sim_fpu *r); 252218893SdimINLINE_SIM_FPU (int) sim_fpu_div (sim_fpu *f, 253243830Sdim const sim_fpu *l, const sim_fpu *r); 254199989SrdivackyINLINE_SIM_FPU (int) sim_fpu_rem (sim_fpu *f, 255234353Sdim const sim_fpu *l, const sim_fpu *r); 256234353SdimINLINE_SIM_FPU (int) sim_fpu_max (sim_fpu *f, 257234982Sdim const sim_fpu *l, const sim_fpu *r); 258239462SdimINLINE_SIM_FPU (int) sim_fpu_min (sim_fpu *f, 259239462Sdim const sim_fpu *l, const sim_fpu *r); 260234982SdimINLINE_SIM_FPU (int) sim_fpu_neg (sim_fpu *f, 261234982Sdim const sim_fpu *a); 262234982SdimINLINE_SIM_FPU (int) sim_fpu_abs (sim_fpu *f, 263234353Sdim const sim_fpu *a); 264243830SdimINLINE_SIM_FPU (int) sim_fpu_inv (sim_fpu *f, 265243830Sdim const sim_fpu *a); 266243830SdimINLINE_SIM_FPU (int) sim_fpu_sqrt (sim_fpu *f, 267243830Sdim const sim_fpu *sqr); 268243830Sdim 269243830Sdim 270243830Sdim 271243830Sdim/* NaN handling. 272243830Sdim 273243830Sdim Assuming that at least one of the inputs is NAN choose the correct 274243830Sdim NAN result for the binary operation. */ 275243830Sdim 276243830SdimINLINE_SIM_FPU (int) sim_fpu_op_nan (sim_fpu *f, 277243830Sdim const sim_fpu *l, const sim_fpu *r); 278239462SdimINLINE_SIM_FPU (int) sim_fpu_minmax_nan (sim_fpu *f, 279239462Sdim const sim_fpu *l, const sim_fpu *r); 280239462Sdim 281193323Sed 282193323Sed 283193323Sed/* Conversion of integer <-> floating point. */ 284193323Sed 285193323SedINLINE_SIM_FPU (int) sim_fpu_i32to (sim_fpu *f, int32_t i, 286193323Sed sim_fpu_round round); 287193323SedINLINE_SIM_FPU (int) sim_fpu_u32to (sim_fpu *f, uint32_t u, 288193323Sed sim_fpu_round round); 289193323SedINLINE_SIM_FPU (int) sim_fpu_i64to (sim_fpu *f, int64_t i, 290193323Sed sim_fpu_round round); 291193323SedINLINE_SIM_FPU (int) sim_fpu_u64to (sim_fpu *f, uint64_t u, 292243830Sdim sim_fpu_round round); 293239462Sdim#if 0 294198090SrdivackyINLINE_SIM_FPU (int) sim_fpu_i232to (sim_fpu *f, int32_t h, int32_t l, 295193323Sed sim_fpu_round round); 296193323Sed#endif 297243830Sdim#if 0 298243830SdimINLINE_SIM_FPU (int) sim_fpu_u232to (sim_fpu *f, uint32_t h, uint32_t l, 299198090Srdivacky sim_fpu_round round); 300193323Sed#endif 301193323Sed 302193323SedINLINE_SIM_FPU (int) sim_fpu_to32i (int32_t *i, const sim_fpu *f, 303221345Sdim sim_fpu_round round); 304221345SdimINLINE_SIM_FPU (int) sim_fpu_to32u (uint32_t *u, const sim_fpu *f, 305193323Sed sim_fpu_round round); 306193323SedINLINE_SIM_FPU (int) sim_fpu_to64i (int64_t *i, const sim_fpu *f, 307234353Sdim sim_fpu_round round); 308234353SdimINLINE_SIM_FPU (int) sim_fpu_to64u (uint64_t *u, const sim_fpu *f, 309243830Sdim sim_fpu_round round); 310234353Sdim#if 0 311239462SdimINLINE_SIM_FPU (int) sim_fpu_to232i (int64_t *h, int64_t *l, const sim_fpu *f, 312234353Sdim sim_fpu_round round); 313234353Sdim#endif 314193323Sed#if 0 315234353SdimINLINE_SIM_FPU (int) sim_fpu_to232u (uint64_t *h, uint64_t *l, const sim_fpu *f, 316234353Sdim sim_fpu_round round); 317234353Sdim#endif 318234353Sdim 319234353Sdim 320218893Sdim/* Conversion of internal sim_fpu type to host double format. 321243830Sdim 322234353Sdim For debugging/tracing only. A SNaN is never returned. */ 323234353Sdim 324193323Sed/* INLINE_SIM_FPU (float) sim_fpu_2f (const sim_fpu *f); */ 325193323SedINLINE_SIM_FPU (double) sim_fpu_2d (const sim_fpu *d); 326193323Sed 327193323Sed/* INLINE_SIM_FPU (void) sim_fpu_f2 (sim_fpu *f, float s); */ 328193323SedINLINE_SIM_FPU (void) sim_fpu_d2 (sim_fpu *f, double d); 329193323Sed 330198090Srdivacky/* IEEE754-2008 classifiction function. */ 331198090SrdivackyINLINE_SIM_FPU (int) sim_fpu_classify (const sim_fpu *f); 332198090Srdivacky 333198090Srdivacky/* Specific number classes. 334198090Srdivacky 335198090Srdivacky NB: When either, a 32/64 bit floating points is converted to 336198090Srdivacky internal format, or an internal format number is rounded to 32/64 337198090Srdivacky bit precision, a special marker is retained that indicates that the 338199989Srdivacky value was normalized. For such numbers both is_number and 339198090Srdivacky is_denorm return true. */ 340226633Sdim 341226633SdimINLINE_SIM_FPU (int) sim_fpu_is_nan (const sim_fpu *s); /* 1 => SNaN or QNaN */ 342193323SedINLINE_SIM_FPU (int) sim_fpu_is_snan (const sim_fpu *s); /* 1 => SNaN */ 343193323SedINLINE_SIM_FPU (int) sim_fpu_is_qnan (const sim_fpu *s); /* 1 => QNaN */ 344193323Sed 345218893SdimINLINE_SIM_FPU (int) sim_fpu_is_zero (const sim_fpu *s); 346218893SdimINLINE_SIM_FPU (int) sim_fpu_is_infinity (const sim_fpu *s); 347218893SdimINLINE_SIM_FPU (int) sim_fpu_is_number (const sim_fpu *s); /* !zero */ 348218893SdimINLINE_SIM_FPU (int) sim_fpu_is_denorm (const sim_fpu *s); /* !zero */ 349218893Sdim 350218893Sdim 351218893Sdim 352218893Sdim/* Floating point fields */ 353218893Sdim 354218893SdimINLINE_SIM_FPU (int) sim_fpu_sign (const sim_fpu *s); 355218893SdimINLINE_SIM_FPU (int) sim_fpu_exp (const sim_fpu *s); 356218893SdimINLINE_SIM_FPU (uint64_t) sim_fpu_fraction (const sim_fpu *s); 357218893SdimINLINE_SIM_FPU (uint64_t) sim_fpu_guard (const sim_fpu *s, int is_double); 358218893Sdim 359218893Sdim 360218893Sdim 361218893Sdim/* Specific comparison operators 362218893Sdim 363218893Sdim For NaNs et al., the comparison operators will set IS to zero and 364218893Sdim return a nonzero result. */ 365218893Sdim 366218893SdimINLINE_SIM_FPU (int) sim_fpu_lt (int *is, const sim_fpu *l, const sim_fpu *r); 367218893SdimINLINE_SIM_FPU (int) sim_fpu_le (int *is, const sim_fpu *l, const sim_fpu *r); 368218893SdimINLINE_SIM_FPU (int) sim_fpu_eq (int *is, const sim_fpu *l, const sim_fpu *r); 369218893SdimINLINE_SIM_FPU (int) sim_fpu_ne (int *is, const sim_fpu *l, const sim_fpu *r); 370193323SedINLINE_SIM_FPU (int) sim_fpu_ge (int *is, const sim_fpu *l, const sim_fpu *r); 371193323SedINLINE_SIM_FPU (int) sim_fpu_gt (int *is, const sim_fpu *l, const sim_fpu *r); 372193323Sed 373193323SedINLINE_SIM_FPU (int) sim_fpu_is_lt (const sim_fpu *l, const sim_fpu *r); 374234353SdimINLINE_SIM_FPU (int) sim_fpu_is_le (const sim_fpu *l, const sim_fpu *r); 375234353SdimINLINE_SIM_FPU (int) sim_fpu_is_eq (const sim_fpu *l, const sim_fpu *r); 376234353SdimINLINE_SIM_FPU (int) sim_fpu_is_ne (const sim_fpu *l, const sim_fpu *r); 377193323SedINLINE_SIM_FPU (int) sim_fpu_is_ge (const sim_fpu *l, const sim_fpu *r); 378218893SdimINLINE_SIM_FPU (int) sim_fpu_is_gt (const sim_fpu *l, const sim_fpu *r); 379218893Sdim 380218893Sdim/* Unordered/ordered comparison operators. */ 381224145Sdim 382226633SdimINLINE_SIM_FPU (int) sim_fpu_un (int *is, const sim_fpu *l, const sim_fpu *r); 383218893SdimINLINE_SIM_FPU (int) sim_fpu_or (int *is, const sim_fpu *l, const sim_fpu *r); 384193323Sed 385218893SdimINLINE_SIM_FPU (int) sim_fpu_is_un (const sim_fpu *l, const sim_fpu *r); 386218893SdimINLINE_SIM_FPU (int) sim_fpu_is_or (const sim_fpu *l, const sim_fpu *r); 387218893Sdim 388224145Sdim/* Changes the behaviour of the library to IEEE754-2008 or IEEE754-1985. 389218893Sdim The default for the library is IEEE754-1985. */ 390218893Sdim 391218893SdimINLINE_SIM_FPU (bool) sim_fpu_is_ieee754_1985 (void); 392218893SdimINLINE_SIM_FPU (bool) sim_fpu_is_ieee754_2008 (void); 393218893SdimINLINE_SIM_FPU (void) sim_fpu_set_mode (const sim_fpu_mode m); 394224145Sdim 395218893Sdim/* General number class and comparison operators. 396218893Sdim 397218893Sdim The result of the comparison is indicated by returning one of the 398218893Sdim values below. Efficient emulation of a target FP compare 399218893Sdim instruction can be achieved by redefining the values below to match 400218893Sdim corresponding target FP status bits. 401218893Sdim 402224145Sdim For instance. SIM_FPU_QNAN may be redefined to be the bit 403218893Sdim `INVALID' while SIM_FPU_NINF might be redefined as the bits 404218893Sdim `NEGATIVE | INFINITY | VALID'. */ 405218893Sdim 406218893Sdim#ifndef SIM_FPU_IS_SNAN 407218893Sdimenum { 408234353Sdim SIM_FPU_IS_SNAN = 1, /* Noisy not-a-number */ 409224145Sdim SIM_FPU_IS_QNAN = 2, /* Quiet not-a-number */ 410218893Sdim SIM_FPU_IS_NINF = 3, /* -infinity */ 411218893Sdim SIM_FPU_IS_PINF = 4, /* +infinity */ 412226633Sdim SIM_FPU_IS_NNUMBER = 5, /* -number - [ -MAX .. -MIN ] */ 413226633Sdim SIM_FPU_IS_PNUMBER = 6, /* +number - [ +MIN .. +MAX ] */ 414226633Sdim SIM_FPU_IS_NDENORM = 7, /* -denorm - ( MIN .. 0 ) */ 415226633Sdim SIM_FPU_IS_PDENORM = 8, /* +denorm - ( 0 .. MIN ) */ 416218893Sdim SIM_FPU_IS_NZERO = 9, /* -0 */ 417193323Sed SIM_FPU_IS_PZERO = 10, /* +0 */ 418226633Sdim}; 419193323Sed#endif 420218893Sdim 421218893SdimINLINE_SIM_FPU (int) sim_fpu_is (const sim_fpu *l); 422193323SedINLINE_SIM_FPU (int) sim_fpu_cmp (const sim_fpu *l, const sim_fpu *r); 423226633Sdim 424193323Sed/* Global FPU state. */ 425193323Sed 426249423Sdimextern sim_fpu_state _sim_fpu; 427249423Sdim 428226633Sdim 429218893Sdim/* IEEE 754-1985 specifies the top bit of the mantissa as an indicator 430218893Sdim of signalling vs. quiet NaN, but does not specify the semantics. 431218893Sdim Most architectures treat this bit as quiet NaN, but legacy (pre-R6) 432218893Sdim MIPS goes the other way and treats it as signalling. This variable 433226633Sdim tracks the current semantics of the NaN bit and allows differentiation 434218893Sdim between pre-R6 and R6 MIPS cores. */ 435218893Sdim 436226633Sdim#define sim_fpu_quiet_nan_inverted _sim_fpu.quiet_nan_inverted 437218893Sdim#define sim_fpu_current_mode _sim_fpu.current_mode 438218893Sdim 439218893Sdim/* A number of useful constants. */ 440218893Sdim 441226633Sdimextern const sim_fpu sim_fpu_zero; 442218893Sdimextern const sim_fpu sim_fpu_one; 443218893Sdimextern const sim_fpu sim_fpu_two; 444193323Sedextern const sim_fpu sim_fpu_qnan; 445193323Sedextern const sim_fpu sim_fpu_max32; 446193323Sedextern const sim_fpu sim_fpu_max64; 447193323Sed 448193323Sed 449193323Sed/* Select the applicable functions for the fp_word type */ 450193323Sed 451193323Sed#if WITH_TARGET_FLOATING_POINT_BITSIZE == 32 452193323Sed#define sim_fpu_tofp sim_fpu_to32 453193323Sed#define sim_fpu_fpto sim_fpu_32to 454218893Sdim#define sim_fpu_round_fp sim_fpu_round_32 455239462Sdim#define sim_fpu_maxfp sim_fpu_max32 456218893Sdim#endif 457218893Sdim#if WITH_TARGET_FLOATING_POINT_BITSIZE == 64 458239462Sdim#define sim_fpu_tofp sim_fpu_to64 459239462Sdim#define sim_fpu_fpto sim_fpu_64to 460218893Sdim#define sim_fpu_round_fp sim_fpu_round_64 461218893Sdim#define sim_fpu_maxfp sim_fpu_max64 462218893Sdim#endif 463218893Sdim 464226633Sdim 465218893Sdim 466218893Sdim/* For debugging */ 467218893Sdim 468226633Sdimtypedef void sim_fpu_print_func (void *, const char *, ...); 469226633Sdim 470226633Sdim/* Print a sim_fpu with full precision. */ 471226633SdimINLINE_SIM_FPU (void) sim_fpu_print_fpu (const sim_fpu *f, 472226633Sdim sim_fpu_print_func *print, 473226633Sdim void *arg); 474226633Sdim 475226633Sdim/* Print a sim_fpu with `n' trailing digits. */ 476226633SdimINLINE_SIM_FPU (void) sim_fpu_printn_fpu (const sim_fpu *f, 477226633Sdim sim_fpu_print_func *print, 478226633Sdim int digits, 479226633Sdim void *arg); 480218893Sdim 481226633SdimINLINE_SIM_FPU (void) sim_fpu_print_status (int status, 482226633Sdim sim_fpu_print_func *print, 483226633Sdim void *arg); 484226633Sdim 485226633Sdim#if H_REVEALS_MODULE_P (SIM_FPU_INLINE) 486226633Sdim#include "sim-fpu.c" 487221345Sdim#endif 488221345Sdim 489212904Sdim#endif 490226633Sdim