1 /** 2 * \file libyasm/floatnum.h 3 * \brief YASM floating point (IEEE) interface. 4 * 5 * \license 6 * Copyright (C) 2001-2007 Peter Johnson 7 * 8 * Based on public-domain x86 assembly code by Randall Hyde (8/28/91). 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * - Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * - Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * \endlicense 31 */ 32 #ifndef YASM_FLOATNUM_H 33 #define YASM_FLOATNUM_H 34 35 #ifndef YASM_LIB_DECL 36 #define YASM_LIB_DECL 37 #endif 38 39 /** Initialize floatnum internal data structures. */ 40 YASM_LIB_DECL 41 void yasm_floatnum_initialize(void); 42 43 /** Clean up internal floatnum allocations. */ 44 YASM_LIB_DECL 45 void yasm_floatnum_cleanup(void); 46 47 /** Create a new floatnum from a decimal string. The input string must be in 48 * standard C representation ([+-]123.456e[-+]789). 49 * \param str floating point decimal string 50 * \return Newly allocated floatnum. 51 */ 52 YASM_LIB_DECL 53 /*@only@*/ yasm_floatnum *yasm_floatnum_create(const char *str); 54 55 /** Duplicate a floatnum. 56 * \param flt floatnum 57 * \return Newly allocated floatnum with the same value as flt. 58 */ 59 YASM_LIB_DECL 60 /*@only@*/ yasm_floatnum *yasm_floatnum_copy(const yasm_floatnum *flt); 61 62 /** Destroy (free allocated memory for) a floatnum. 63 * \param flt floatnum 64 */ 65 YASM_LIB_DECL 66 void yasm_floatnum_destroy(/*@only@*/ yasm_floatnum *flt); 67 68 /** Floating point calculation function: acc = acc op operand. 69 * \note Not all operations in yasm_expr_op may be supported; unsupported 70 * operations will result in an error. 71 * \param acc floatnum accumulator 72 * \param op operation 73 * \param operand floatnum operand 74 * \return Nonzero on error. 75 */ 76 YASM_LIB_DECL 77 int yasm_floatnum_calc(yasm_floatnum *acc, yasm_expr_op op, 78 yasm_floatnum *operand); 79 80 /** Convert a floatnum to single-precision and return as 32-bit value. 81 * The 32-bit value is a "standard" C value (eg, of unknown endian). 82 * \param flt floatnum 83 * \param ret_val pointer to storage for 32-bit output 84 * \return Nonzero if flt can't fit into single precision: -1 if underflow 85 * occurred, 1 if overflow occurred. 86 */ 87 YASM_LIB_DECL 88 int yasm_floatnum_get_int(const yasm_floatnum *flt, 89 /*@out@*/ unsigned long *ret_val); 90 91 /** Output a #yasm_floatnum to buffer in little-endian or big-endian. Puts the 92 * value into the least significant bits of the destination, or may be shifted 93 * into more significant bits by the shift parameter. The destination bits are 94 * cleared before being set. [0] should be the first byte output to the file. 95 * \note Not all sizes are valid. Currently, only 32 (single-precision), 64 96 * (double-precision), and 80 (extended-precision) are valid sizes. 97 * Use yasm_floatnum_check_size() to check for supported sizes. 98 * \param flt floatnum 99 * \param ptr pointer to storage for size bytes of output 100 * \param destsize destination size (in bytes) 101 * \param valsize size (in bits) 102 * \param shift left shift (in bits) 103 * \param bigendian endianness (nonzero=big, zero=little) 104 * \param warn enables standard overflow/underflow warnings 105 * \return Nonzero if flt can't fit into the specified precision: -1 if 106 * underflow occurred, 1 if overflow occurred. 107 */ 108 YASM_LIB_DECL 109 int yasm_floatnum_get_sized(const yasm_floatnum *flt, unsigned char *ptr, 110 size_t destsize, size_t valsize, size_t shift, 111 int bigendian, int warn); 112 113 /** Basic check to see if size is valid for flt conversion (using 114 * yasm_floatnum_get_sized()). Doesn't actually check for underflow/overflow 115 * but rather checks for size=32,64,80 116 * (at present). 117 * \param flt floatnum 118 * \param size number of bits of output space 119 * \return 1 if valid size, 0 if invalid size. 120 */ 121 YASM_LIB_DECL 122 int yasm_floatnum_check_size(const yasm_floatnum *flt, size_t size); 123 124 /** Print various representations of a floatnum. For debugging purposes only. 125 * \param f file 126 * \param flt floatnum 127 */ 128 YASM_LIB_DECL 129 void yasm_floatnum_print(const yasm_floatnum *flt, FILE *f); 130 131 #endif 132