Files
sigmaker-ida/idasdk75/include/ieee.h
2021-06-05 21:10:25 +03:00

307 lines
7.6 KiB
C

/*
* Interactive disassembler (IDA)
* Copyright (c) 1990-2020 Hex-Rays
* ALL RIGHTS RESERVED.
* Floating Point Number Libary.
* Copyright (c) 1995-2006 by Iouri Kharon.
* E-mail: yjh@styx.cabel.net
*
*/
#ifndef _IEEE_H_
#define _IEEE_H_
/*! \file ieee.h
\brief IEEE floating point functions
*/
//-------------------------------------------------------------------
/// Number of 16 bit words in ::eNE
#define IEEE_NE 6
/// Number of 16 bit words in ::eNI
#define IEEE_NI (IEEE_NE+3)
//==========================================================================
/// Array offset to exponent
#define IEEE_E 1
/// Array offset to high guard word
#define IEEE_M 2
/// The exponent of 1.0
#define IEEE_EXONE (0x3fff)
//===================================================================
/// External x type format
typedef uint16 eNE[IEEE_NE];
/// Internal format:
/// - 0 : sign (0/1)
/// - 1 : exponent (based of #IEEE_EXONE). If exp = 0, value = 0.
/// - 2 : high word of mantissa (always zero after normalize)
typedef uint16 eNI[IEEE_NI];
/// Exponent in eNE for NaN and Inf
#define E_SPECIAL_EXP 0x7fff
/// 0.0
extern const eNE ieee_ezero;
#define EZERO { 0, 0000000,0000000,0000000,0000000,0000000 }
/// 1.0
extern const eNE ieee_eone;
#define EONE { 0, 0000000,0000000,0000000,0100000,0x3fff }
/// 2.0
extern const eNE ieee_etwo;
/// 32.0
extern const eNE ieee_e32;
/// 6.93147180559945309417232121458176568075500134360255E-1
extern const eNE ieee_elog2;
/// 1.41421356237309504880168872420969807856967187537695E0
extern const eNE ieee_esqrt2;
/// 2/sqrt(PI) = 1.12837916709551257389615890312154517168810125865800E0
extern const eNE ieee_eoneopi;
/// 3.14159265358979323846264338327950288419716939937511E0
extern const eNE ieee_epi;
/// 5.7721566490153286060651209008240243104215933593992E-1
extern const eNE ieee_eeul;
/// Clear (zero-out) the given value
inline void ecleaz(eNI x) { memset(x, 0, sizeof(eNI)); }
/// Move eNI => eNE
idaman THREAD_SAFE void ida_export emovo(const eNI a, eNE b);
/// Move eNE => eNI
idaman THREAD_SAFE void ida_export emovi(const eNE a, eNI b);
/// Shift NI format up (+) or down
idaman THREAD_SAFE int ida_export eshift(eNI x, int sc);
/// Normalize and round off.
/// \param s the internal format number to be rounded
/// \param lost indicates whether or not the number is exact.
/// this is the so-called sticky bit.
/// \param subflg indicates whether the number was obtained
/// by a subtraction operation. In that case if lost is nonzero
/// then the number is slightly smaller than indicated.
/// \param exp the biased exponent, which may be negative.
/// the exponent field of "s" is ignored but is replaced by
/// "exp" as adjusted by normalization and rounding.
/// \param rndbase if 0 => is the rounding control.
/// else is processor defined base (rndprc)
/// \return success
idaman THREAD_SAFE int ida_export emdnorm(eNI s, int lost, int subflg, int32 exp, int rndbase);
/// \defgroup REAL_ERROR_ Floating point/IEEE Conversion codes
/// Return values for and processor_t::realcvt_t request
//@{
#define REAL_ERROR_FORMAT -1 ///< not supported format for current .idp
#define REAL_ERROR_RANGE -2 ///< number too big (small) for store (mem NOT modified)
#define REAL_ERROR_BADDATA -3 ///< illegal real data for load (IEEE data not filled)
//@}
//
/// \name Prototypes
/// IDP module event prototype -- should be implemented in idp
//@{
/// Floating point conversion function: implemented by \ph{realcvt}.
/// \param m pointer to data
/// \param e internal IEEE format data
/// \param swt operation:
/// - 000: load trunc. float (DEC ^F) 2 bytes (m->e)
/// - 001: load float 4 bytes (m->e)
/// - 003: load double 8 bytes (m->e)
/// - 004: load long double 10 bytes (m->e)
/// - 005: load long double 12 bytes (m->e)
/// - 010: store trunc. float (DEC ^F) 2 bytes (e->m)
/// - 011: store float 4 bytes (e->m)
/// - 013: store double 8 bytes (e->m)
/// - 014: store long double 10 bytes (e->m)
/// - 015: store long double 12 bytes (e->m)
/// \retval 0 ok
/// \retval \ref REAL_ERROR_ on error
int idaapi realcvt(void *m, eNE e, uint16 swt);
/// Little endian
int l_realcvt(void *m, eNE e, uint16 swt);
/// Big endian
int b_realcvt(void *m, eNE e, uint16 swt);
//@}
/// Standard IEEE 754 floating point conversion function.
/// See comment for realcvt().
idaman THREAD_SAFE int ida_export ieee_realcvt(void *m, eNE e, uint16 swt);
/// \name Misc arithmetic/conversion functions
/// \retval 0 ok
/// \retval 1 overfloat / underfloat
/// \retval 2 illegal data (asctoreal())
/// \retval 3 divide by 0 (ediv())
/// \retval 4 too big for integer (eetol())
//@{
/// IEEE to ascii string.
/// \param mode broken down into:
/// - low byte: number of digits after '.'
/// - second byte: FPNUM_LENGTH
/// - third byte: FPNUM_DIGITS
idaman THREAD_SAFE void ida_export realtoasc(char *buf, size_t bufsize, const eNE x, uint mode);
/// ascii string to IEEE
idaman THREAD_SAFE int ida_export asctoreal(const char **sss, eNE y);
/// long to IEEE
idaman THREAD_SAFE void ida_export eltoe(sval_t l, eNE e);
/// int64 to IEEE
idaman THREAD_SAFE void ida_export eltoe64(int64 l, eNE e);
/// uint64 to IEEE
idaman THREAD_SAFE void ida_export eltoe64u(uint64 l, eNE e);
/// IEEE to long (+-0.5 if flg)
idaman THREAD_SAFE int ida_export eetol(sval_t *l, const eNE a, bool roundflg);
/// IEEE to long (+-0.5 if flg)
idaman THREAD_SAFE int ida_export eetol64(int64 *l, const eNE a, bool roundflg);
/// IEEE to ulong (+-0.5 if flg)
idaman THREAD_SAFE int ida_export eetol64u(uint64 *l, const eNE a, bool roundflg);
/// b = a*(2**pwr2)
idaman THREAD_SAFE int ida_export eldexp(const eNE a, int32 pwr2, eNE b);
/// if(!subflg) c = a + b,
/// else c = a - b
idaman THREAD_SAFE int ida_export eadd(const eNE a, const eNE b, eNE c, int subflg);
/// c = a * b
idaman THREAD_SAFE int ida_export emul(const eNE a, const eNE b, eNE c);
/// c = a / b
idaman THREAD_SAFE int ida_export ediv(const eNE a, const eNE b, eNE c);
// predefined functions
/// \cond
void eclear(eNE a);
void emov(eNE a, eNE b);
void eabs(eNE x);
int esign(eNE x);
/// \endcond
/// x = 0
#define eclear(a) memset(a, 0, sizeof(eNE))
/// b = a
#define emov(a, b) memcpy(b, a, sizeof(eNE))
/// x = |x|
#define eabs(x) (x[IEEE_NE-1] &= 0x7fff)
#ifdef __cplusplus
/// x = -x
inline void eneg(eNE x)
{
if ( x[IEEE_NE-1] != 0 )
x[IEEE_NE-1] ^= 0x8000;
}
#endif
/// x < 0 ?
/// \note non standard answer is returned
#define esign(x) (x[IEEE_NE-1] & 0x8000)
//@}
/// Comparison.
/// \retval 0 if a = b
/// \retval 1 if a > b
/// \retval -1 if a < b
idaman THREAD_SAFE int ida_export ecmp(const eNE a, const eNE b);
/// Check for NaN/Inf
enum fpvalue_kind_t
{
FPV_BADARG, ///< wrong value of max_exp
FPV_NORM, ///< regular value
FPV_NAN, ///< NaN
FPV_PINF, ///< positive infinity
FPV_NINF, ///< negative infinity
};
/// \name max_exp values
/// common values for max_exp (for IEEE floating point values)
//@{
const uint32
MAXEXP_FLOAT = 0x80,
MAXEXP_DOUBLE = 0x400,
MAXEXP_LNGDBL = 0x4000;
//@}
/// See ::fpvalue_kind_t
idaman THREAD_SAFE fpvalue_kind_t ida_export get_fpvalue_kind(const eNE a, uint16 reserved = 0);
#endif