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);