Home | History | Annotate | Download | only in libyasm
      1 /**
      2  * \file libyasm/intnum.h
      3  * \brief YASM integer number interface.
      4  *
      5  * \license
      6  *  Copyright (C) 2001-2007  Peter Johnson
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *  - Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  *  - Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
     18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
     21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27  * POSSIBILITY OF SUCH DAMAGE.
     28  * \endlicense
     29  */
     30 #ifndef YASM_INTNUM_H
     31 #define YASM_INTNUM_H
     32 
     33 #ifndef YASM_LIB_DECL
     34 #define YASM_LIB_DECL
     35 #endif
     36 
     37 /** Initialize intnum internal data structures. */
     38 YASM_LIB_DECL
     39 void yasm_intnum_initialize(void);
     40 
     41 /** Clean up internal intnum allocations. */
     42 YASM_LIB_DECL
     43 void yasm_intnum_cleanup(void);
     44 
     45 /** Create a new intnum from a decimal string.
     46  * \param str       decimal string
     47  * \return Newly allocated intnum.
     48  */
     49 YASM_LIB_DECL
     50 /*@only@*/ yasm_intnum *yasm_intnum_create_dec(char *str);
     51 
     52 /** Create a new intnum from a binary string.
     53  * \param str       binary string
     54  * \return Newly allocated intnum.
     55  */
     56 YASM_LIB_DECL
     57 /*@only@*/ yasm_intnum *yasm_intnum_create_bin(char *str);
     58 
     59 /** Create a new intnum from an octal string.
     60  * \param str       octal string
     61  * \return Newly allocated intnum.
     62  */
     63 YASM_LIB_DECL
     64 /*@only@*/ yasm_intnum *yasm_intnum_create_oct(char *str);
     65 
     66 /** Create a new intnum from a hexidecimal string.
     67  * \param str       hexidecimal string
     68  * \return Newly allocated intnum.
     69  */
     70 YASM_LIB_DECL
     71 /*@only@*/ yasm_intnum *yasm_intnum_create_hex(char *str);
     72 
     73 /** Convert character constant to integer value, using NASM rules.  NASM syntax
     74  * supports automatic conversion from strings such as 'abcd' to a 32-bit
     75  * integer value (little endian order).  This function performs those conversions.
     76  * \param str       character constant string
     77  * \return Newly allocated intnum.
     78  */
     79 YASM_LIB_DECL
     80 /*@only@*/ yasm_intnum *yasm_intnum_create_charconst_nasm(const char *str);
     81 
     82 /** Convert character constant to integer value, using TASM rules.  TASM syntax
     83  * supports automatic conversion from strings such as 'abcd' to a 32-bit
     84  * integer value (big endian order).  This function performs those conversions.
     85  * \param str       character constant string
     86  * \return Newly allocated intnum.
     87  */
     88 YASM_LIB_DECL
     89 /*@only@*/ yasm_intnum *yasm_intnum_create_charconst_tasm(const char *str);
     90 
     91 /** Create a new intnum from an unsigned integer value.
     92  * \param i         unsigned integer value
     93  * \return Newly allocated intnum.
     94  */
     95 YASM_LIB_DECL
     96 /*@only@*/ yasm_intnum *yasm_intnum_create_uint(unsigned long i);
     97 
     98 /** Create a new intnum from an signed integer value.
     99  * \param i         signed integer value
    100  * \return Newly allocated intnum.
    101  */
    102 YASM_LIB_DECL
    103 /*@only@*/ yasm_intnum *yasm_intnum_create_int(long i);
    104 
    105 /** Create a new intnum from LEB128-encoded form.
    106  * \param ptr   pointer to start of LEB128 encoded form
    107  * \param sign  signed (1) or unsigned (0) LEB128 format
    108  * \param size  number of bytes read from ptr (output)
    109  * \return Newly allocated intnum.  Number of bytes read returned into
    110  *         bytes_read parameter.
    111  */
    112 YASM_LIB_DECL
    113 /*@only@*/ yasm_intnum *yasm_intnum_create_leb128
    114     (const unsigned char *ptr, int sign, /*@out@*/ unsigned long *size);
    115 
    116 /** Create a new intnum from a little-endian or big-endian buffer.
    117  * In little endian, the LSB is in ptr[0].
    118  * \param ptr       pointer to start of buffer
    119  * \param sign      signed (1) or unsigned (0) source
    120  * \param srcsize   source buffer size (in bytes)
    121  * \param bigendian endianness (nonzero=big, zero=little)
    122  */
    123 YASM_LIB_DECL
    124 /*@only@*/ yasm_intnum *yasm_intnum_create_sized
    125     (unsigned char *ptr, int sign, size_t srcsize, int bigendian);
    126 
    127 /** Duplicate an intnum.
    128  * \param intn  intnum
    129  * \return Newly allocated intnum with the same value as intn.
    130  */
    131 YASM_LIB_DECL
    132 /*@only@*/ yasm_intnum *yasm_intnum_copy(const yasm_intnum *intn);
    133 
    134 /** Destroy (free allocated memory for) an intnum.
    135  * \param intn  intnum
    136  */
    137 YASM_LIB_DECL
    138 void yasm_intnum_destroy(/*@only@*/ yasm_intnum *intn);
    139 
    140 /** Floating point calculation function: acc = acc op operand.
    141  * \note Not all operations in yasm_expr_op may be supported; unsupported
    142  *       operations will result in an error.
    143  * \param acc       intnum accumulator
    144  * \param op        operation
    145  * \param operand   intnum operand
    146  * \return Nonzero if error occurred.
    147  */
    148 YASM_LIB_DECL
    149 int yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand);
    150 
    151 /** Compare two intnums.
    152  * \param intn1     first intnum
    153  * \param intn2     second intnum
    154  * \return -1 if intn1 < intn2, 0 if intn1 == intn2, 1 if intn1 > intn2.
    155  */
    156 YASM_LIB_DECL
    157 int yasm_intnum_compare(const yasm_intnum *intn1, const yasm_intnum *intn2);
    158 
    159 /** Zero an intnum.
    160  * \param intn      intnum
    161  */
    162 YASM_LIB_DECL
    163 void yasm_intnum_zero(yasm_intnum *intn);
    164 
    165 /** Set an intnum to the value of another intnum.
    166  * \param intn      intnum
    167  * \param val       intnum to get value from
    168  */
    169 YASM_LIB_DECL
    170 void yasm_intnum_set(yasm_intnum *intn, const yasm_intnum *val);
    171 
    172 /** Set an intnum to an unsigned integer.
    173  * \param intn      intnum
    174  * \param val       integer value
    175  */
    176 YASM_LIB_DECL
    177 void yasm_intnum_set_uint(yasm_intnum *intn, unsigned long val);
    178 
    179 /** Set an intnum to an signed integer.
    180  * \param intn      intnum
    181  * \param val       integer value
    182  */
    183 YASM_LIB_DECL
    184 void yasm_intnum_set_int(yasm_intnum *intn, long val);
    185 
    186 /** Simple value check for 0.
    187  * \param acc       intnum
    188  * \return Nonzero if acc==0.
    189  */
    190 YASM_LIB_DECL
    191 int yasm_intnum_is_zero(const yasm_intnum *acc);
    192 
    193 /** Simple value check for 1.
    194  * \param acc       intnum
    195  * \return Nonzero if acc==1.
    196  */
    197 YASM_LIB_DECL
    198 int yasm_intnum_is_pos1(const yasm_intnum *acc);
    199 
    200 /** Simple value check for -1.
    201  * \param acc       intnum
    202  * \return Nonzero if acc==-1.
    203  */
    204 YASM_LIB_DECL
    205 int yasm_intnum_is_neg1(const yasm_intnum *acc);
    206 
    207 /** Simple sign check.
    208  * \param acc       intnum
    209  * \return -1 if negative, 0 if zero, +1 if positive
    210  */
    211 YASM_LIB_DECL
    212 int yasm_intnum_sign(const yasm_intnum *acc);
    213 
    214 /** Convert an intnum to an unsigned 32-bit value.  The value is in "standard"
    215  * C format (eg, of unknown endian).
    216  * \note Parameter intnum is truncated to fit into 32 bits.  Use
    217  *       intnum_check_size() to check for overflow.
    218  * \param intn  intnum
    219  * \return Unsigned 32-bit value of intn.
    220  */
    221 YASM_LIB_DECL
    222 unsigned long yasm_intnum_get_uint(const yasm_intnum *intn);
    223 
    224 /** Convert an intnum to a signed 32-bit value.  The value is in "standard" C
    225  * format (eg, of unknown endian).
    226  * \note Parameter intnum is truncated to fit into 32 bits.  Use
    227  *       intnum_check_size() to check for overflow.
    228  * \param intn  intnum
    229  * \return Signed 32-bit value of intn.
    230  */
    231 YASM_LIB_DECL
    232 long yasm_intnum_get_int(const yasm_intnum *intn);
    233 
    234 /** Output #yasm_intnum to buffer in little-endian or big-endian.  Puts the
    235  * value into the least significant bits of the destination, or may be shifted
    236  * into more significant bits by the shift parameter.  The destination bits are
    237  * cleared before being set.  [0] should be the first byte output to the file.
    238  * \param intn      intnum
    239  * \param ptr       pointer to storage for size bytes of output
    240  * \param destsize  destination size (in bytes)
    241  * \param valsize   size (in bits)
    242  * \param shift     left shift (in bits); may be negative to specify right
    243  *                  shift (standard warnings include truncation to boundary)
    244  * \param bigendian endianness (nonzero=big, zero=little)
    245  * \param warn      enables standard warnings (value doesn't fit into valsize
    246  *                  bits): <0=signed warnings, >0=unsigned warnings, 0=no warn
    247  */
    248 YASM_LIB_DECL
    249 void yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
    250                            size_t destsize, size_t valsize, int shift,
    251                            int bigendian, int warn);
    252 
    253 /** Check to see if intnum will fit without overflow into size bits.
    254  * \param intn      intnum
    255  * \param size      number of bits of output space
    256  * \param rshift    right shift
    257  * \param rangetype signed/unsigned range selection:
    258  *                  0 => (0, unsigned max);
    259  *                  1 => (signed min, signed max);
    260  *                  2 => (signed min, unsigned max)
    261  * \return Nonzero if intnum will fit.
    262  */
    263 YASM_LIB_DECL
    264 int yasm_intnum_check_size(const yasm_intnum *intn, size_t size,
    265                            size_t rshift, int rangetype);
    266 
    267 /** Check to see if intnum will fit into a particular numeric range.
    268  * \param intn      intnum
    269  * \param low       low end of range (inclusive)
    270  * \param high      high end of range (inclusive)
    271  * \return Nonzero if intnum is within range.
    272  */
    273 YASM_LIB_DECL
    274 int yasm_intnum_in_range(const yasm_intnum *intn, long low, long high);
    275 
    276 /** Output #yasm_intnum to buffer in LEB128-encoded form.
    277  * \param intn      intnum
    278  * \param ptr       pointer to storage for output bytes
    279  * \param sign      signedness of LEB128 encoding (0=unsigned, 1=signed)
    280  * \return Number of bytes generated.
    281  */
    282 YASM_LIB_DECL
    283 unsigned long yasm_intnum_get_leb128(const yasm_intnum *intn,
    284                                      unsigned char *ptr, int sign);
    285 
    286 /** Calculate number of bytes LEB128-encoded form of #yasm_intnum will take.
    287  * \param intn      intnum
    288  * \param sign      signedness of LEB128 encoding (0=unsigned, 1=signed)
    289  * \return Number of bytes.
    290  */
    291 YASM_LIB_DECL
    292 unsigned long yasm_intnum_size_leb128(const yasm_intnum *intn, int sign);
    293 
    294 /** Output integer to buffer in signed LEB128-encoded form.
    295  * \param v         integer
    296  * \param ptr       pointer to storage for output bytes
    297  * \return Number of bytes generated.
    298  */
    299 YASM_LIB_DECL
    300 unsigned long yasm_get_sleb128(long v, unsigned char *ptr);
    301 
    302 /** Calculate number of bytes signed LEB128-encoded form of integer will take.
    303  * \param v         integer
    304  * \return Number of bytes.
    305  */
    306 YASM_LIB_DECL
    307 unsigned long yasm_size_sleb128(long v);
    308 
    309 /** Output integer to buffer in unsigned LEB128-encoded form.
    310  * \param v         integer
    311  * \param ptr       pointer to storage for output bytes
    312  * \return Number of bytes generated.
    313  */
    314 YASM_LIB_DECL
    315 unsigned long yasm_get_uleb128(unsigned long v, unsigned char *ptr);
    316 
    317 /** Calculate number of bytes unsigned LEB128-encoded form of integer will take.
    318  * \param v         integer
    319  * \return Number of bytes.
    320  */
    321 YASM_LIB_DECL
    322 unsigned long yasm_size_uleb128(unsigned long v);
    323 
    324 /** Get an intnum as a signed decimal string.  The returned string will
    325  * contain a leading '-' if the intnum is negative.
    326  * \param intn  intnum
    327  * \return Newly allocated string containing the decimal representation of
    328  *         the intnum.
    329  */
    330 YASM_LIB_DECL
    331 /*@only@*/ char *yasm_intnum_get_str(const yasm_intnum *intn);
    332 
    333 /** Print an intnum.  For debugging purposes.
    334  * \param f     file
    335  * \param intn  intnum
    336  */
    337 YASM_LIB_DECL
    338 void yasm_intnum_print(const yasm_intnum *intn, FILE *f);
    339 
    340 #endif
    341