2 * \file libyasm/intnum.h
3 * \brief YASM integer number interface.
6 * Copyright (C) 2001-2007 Peter Johnson
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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.
37 /** Initialize intnum internal data structures. */
39 void yasm_intnum_initialize(void);
41 /** Clean up internal intnum allocations. */
43 void yasm_intnum_cleanup(void);
45 /** Create a new intnum from a decimal string.
46 * \param str decimal string
47 * \return Newly allocated intnum.
50 /*@only@*/ yasm_intnum *yasm_intnum_create_dec(char *str);
52 /** Create a new intnum from a binary string.
53 * \param str binary string
54 * \return Newly allocated intnum.
57 /*@only@*/ yasm_intnum *yasm_intnum_create_bin(char *str);
59 /** Create a new intnum from an octal string.
60 * \param str octal string
61 * \return Newly allocated intnum.
64 /*@only@*/ yasm_intnum *yasm_intnum_create_oct(char *str);
66 /** Create a new intnum from a hexidecimal string.
67 * \param str hexidecimal string
68 * \return Newly allocated intnum.
71 /*@only@*/ yasm_intnum *yasm_intnum_create_hex(char *str);
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.
80 /*@only@*/ yasm_intnum *yasm_intnum_create_charconst_nasm(const char *str);
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.
89 /*@only@*/ yasm_intnum *yasm_intnum_create_charconst_tasm(const char *str);
91 /** Create a new intnum from an unsigned integer value.
92 * \param i unsigned integer value
93 * \return Newly allocated intnum.
96 /*@only@*/ yasm_intnum *yasm_intnum_create_uint(unsigned long i);
98 /** Create a new intnum from an signed integer value.
99 * \param i signed integer value
100 * \return Newly allocated intnum.
103 /*@only@*/ yasm_intnum *yasm_intnum_create_int(long i);
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.
113 /*@only@*/ yasm_intnum *yasm_intnum_create_leb128
114 (const unsigned char *ptr, int sign, /*@out@*/ unsigned long *size);
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)
124 /*@only@*/ yasm_intnum *yasm_intnum_create_sized
125 (unsigned char *ptr, int sign, size_t srcsize, int bigendian);
127 /** Duplicate an intnum.
129 * \return Newly allocated intnum with the same value as intn.
132 /*@only@*/ yasm_intnum *yasm_intnum_copy(const yasm_intnum *intn);
134 /** Destroy (free allocated memory for) an intnum.
138 void yasm_intnum_destroy(/*@only@*/ yasm_intnum *intn);
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.
149 int yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand);
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.
157 int yasm_intnum_compare(const yasm_intnum *intn1, const yasm_intnum *intn2);
163 void yasm_intnum_zero(yasm_intnum *intn);
165 /** Set an intnum to the value of another intnum.
167 * \param val intnum to get value from
170 void yasm_intnum_set(yasm_intnum *intn, const yasm_intnum *val);
172 /** Set an intnum to an unsigned integer.
174 * \param val integer value
177 void yasm_intnum_set_uint(yasm_intnum *intn, unsigned long val);
179 /** Set an intnum to an signed integer.
181 * \param val integer value
184 void yasm_intnum_set_int(yasm_intnum *intn, long val);
186 /** Simple value check for 0.
188 * \return Nonzero if acc==0.
191 int yasm_intnum_is_zero(const yasm_intnum *acc);
193 /** Simple value check for 1.
195 * \return Nonzero if acc==1.
198 int yasm_intnum_is_pos1(const yasm_intnum *acc);
200 /** Simple value check for -1.
202 * \return Nonzero if acc==-1.
205 int yasm_intnum_is_neg1(const yasm_intnum *acc);
207 /** Simple sign check.
209 * \return -1 if negative, 0 if zero, +1 if positive
212 int yasm_intnum_sign(const yasm_intnum *acc);
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.
219 * \return Unsigned 32-bit value of intn.
222 unsigned long yasm_intnum_get_uint(const yasm_intnum *intn);
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.
229 * \return Signed 32-bit value of intn.
232 long yasm_intnum_get_int(const yasm_intnum *intn);
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.
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
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);
253 /** Check to see if intnum will fit without overflow into size bits.
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.
264 int yasm_intnum_check_size(const yasm_intnum *intn, size_t size,
265 size_t rshift, int rangetype);
267 /** Check to see if intnum will fit into a particular numeric range.
269 * \param low low end of range (inclusive)
270 * \param high high end of range (inclusive)
271 * \return Nonzero if intnum is within range.
274 int yasm_intnum_in_range(const yasm_intnum *intn, long low, long high);
276 /** Output #yasm_intnum to buffer in LEB128-encoded form.
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.
283 unsigned long yasm_intnum_get_leb128(const yasm_intnum *intn,
284 unsigned char *ptr, int sign);
286 /** Calculate number of bytes LEB128-encoded form of #yasm_intnum will take.
288 * \param sign signedness of LEB128 encoding (0=unsigned, 1=signed)
289 * \return Number of bytes.
292 unsigned long yasm_intnum_size_leb128(const yasm_intnum *intn, int sign);
294 /** Output integer to buffer in signed LEB128-encoded form.
296 * \param ptr pointer to storage for output bytes
297 * \return Number of bytes generated.
300 unsigned long yasm_get_sleb128(long v, unsigned char *ptr);
302 /** Calculate number of bytes signed LEB128-encoded form of integer will take.
304 * \return Number of bytes.
307 unsigned long yasm_size_sleb128(long v);
309 /** Output integer to buffer in unsigned LEB128-encoded form.
311 * \param ptr pointer to storage for output bytes
312 * \return Number of bytes generated.
315 unsigned long yasm_get_uleb128(unsigned long v, unsigned char *ptr);
317 /** Calculate number of bytes unsigned LEB128-encoded form of integer will take.
319 * \return Number of bytes.
322 unsigned long yasm_size_uleb128(unsigned long v);
324 /** Get an intnum as a signed decimal string. The returned string will
325 * contain a leading '-' if the intnum is negative.
327 * \return Newly allocated string containing the decimal representation of
331 /*@only@*/ char *yasm_intnum_get_str(const yasm_intnum *intn);
333 /** Print an intnum. For debugging purposes.
338 void yasm_intnum_print(const yasm_intnum *intn, FILE *f);