* intnum.h (yasm_get_sleb128, yasm_size_sleb128): New functions to handle

signed LEB128-encoded numbers straight from long values (rather than going
through intnum).
(yasm_get_uleb128, yasm_size_uleb128): Likewise, for unsigned LEB128.
* intnum.c (get_leb128, size_leb128): Move most of functionality here from:
(yasm_intnum_get_leb128, yasm_intnum_size_leb128): Here (refactor).
(yasm_get_sleb128, yasm_size_sleb128, yasm_get_uleb128, yasm_size_uleb128):
Implement using refactored functionality.

svn path=/trunk/yasm/; revision=1366
0.5.0rc2
Peter Johnson 19 years ago
parent d69bb359ba
commit 91ac655c47
  1. 141
      libyasm/intnum.c
  2. 26
      libyasm/intnum.h

@ -656,27 +656,12 @@ yasm_intnum_check_size(const yasm_intnum *intn, size_t size, size_t rshift,
return (Set_Max(val) < (long)size);
}
unsigned long
yasm_intnum_get_leb128(const yasm_intnum *intn, unsigned char *ptr, int sign)
static unsigned long
get_leb128(wordptr val, unsigned char *ptr, int sign)
{
wordptr val = op1static;
unsigned long i, size;
unsigned char *ptr_orig = ptr;
/* Shortcut 0 */
if (intn->type == INTNUM_UL && intn->val.ul == 0) {
*ptr = 0;
return 1;
}
/* If not already a bitvect, convert value to be written to a bitvect */
if (intn->type == INTNUM_BV)
val = intn->val.bv;
else {
BitVector_Empty(val);
BitVector_Chunk_Store(val, 32, 0, intn->val.ul);
}
if (sign) {
/* Signed mode */
if (BitVector_msb_(val)) {
@ -702,6 +687,47 @@ yasm_intnum_get_leb128(const yasm_intnum *intn, unsigned char *ptr, int sign)
return (unsigned long)(ptr-ptr_orig);
}
static unsigned long
size_leb128(wordptr val, int sign)
{
if (sign) {
/* Signed mode */
if (BitVector_msb_(val)) {
/* Negative */
BitVector_Negate(conv_bv, val);
return (Set_Max(conv_bv)+8)/7;
} else {
/* Positive */
return (Set_Max(val)+8)/7;
}
} else {
/* Unsigned mode */
return (Set_Max(val)+7)/7;
}
}
unsigned long
yasm_intnum_get_leb128(const yasm_intnum *intn, unsigned char *ptr, int sign)
{
wordptr val = op1static;
/* Shortcut 0 */
if (intn->type == INTNUM_UL && intn->val.ul == 0) {
*ptr = 0;
return 1;
}
/* If not already a bitvect, convert value to be written to a bitvect */
if (intn->type == INTNUM_BV)
val = intn->val.bv;
else {
BitVector_Empty(val);
BitVector_Chunk_Store(val, 32, 0, intn->val.ul);
}
return get_leb128(val, ptr, sign);
}
unsigned long
yasm_intnum_size_leb128(const yasm_intnum *intn, int sign)
{
@ -720,20 +746,75 @@ yasm_intnum_size_leb128(const yasm_intnum *intn, int sign)
BitVector_Chunk_Store(val, 32, 0, intn->val.ul);
}
if (sign) {
/* Signed mode */
if (BitVector_msb_(val)) {
/* Negative */
BitVector_Negate(conv_bv, val);
return (Set_Max(conv_bv)+8)/7;
} else {
/* Positive */
return (Set_Max(val)+8)/7;
}
} else {
/* Unsigned mode */
return (Set_Max(val)+7)/7;
return size_leb128(val, sign);
}
unsigned long
yasm_get_sleb128(long v, unsigned char *ptr)
{
wordptr val = op1static;
/* Shortcut 0 */
if (v == 0) {
*ptr = 0;
return 1;
}
BitVector_Empty(val);
if (v >= 0)
BitVector_Chunk_Store(val, 32, 0, (unsigned long)v);
else {
BitVector_Chunk_Store(val, 32, 0, (unsigned long)(-v));
BitVector_Negate(val, val);
}
return get_leb128(val, ptr, 1);
}
unsigned long
yasm_size_sleb128(long v)
{
wordptr val = op1static;
if (v == 0)
return 1;
BitVector_Empty(val);
if (v >= 0)
BitVector_Chunk_Store(val, 32, 0, (unsigned long)v);
else {
BitVector_Chunk_Store(val, 32, 0, (unsigned long)(-v));
BitVector_Negate(val, val);
}
return size_leb128(val, 1);
}
unsigned long
yasm_get_uleb128(unsigned long v, unsigned char *ptr)
{
wordptr val = op1static;
/* Shortcut 0 */
if (v == 0) {
*ptr = 0;
return 1;
}
BitVector_Empty(val);
BitVector_Chunk_Store(val, 32, 0, v);
return get_leb128(val, ptr, 0);
}
unsigned long
yasm_size_uleb128(unsigned long v)
{
wordptr val = op1static;
if (v == 0)
return 1;
BitVector_Empty(val);
BitVector_Chunk_Store(val, 32, 0, v);
return size_leb128(val, 0);
}
void

@ -214,6 +214,32 @@ unsigned long yasm_intnum_get_leb128(const yasm_intnum *intn,
*/
unsigned long yasm_intnum_size_leb128(const yasm_intnum *intn, int sign);
/** Output integer to buffer in signed LEB128-encoded form.
* \param v integer
* \param ptr pointer to storage for output bytes
* \return Number of bytes generated.
*/
unsigned long yasm_get_sleb128(long v, unsigned char *ptr);
/** Calculate number of bytes signed LEB128-encoded form of integer will take.
* \param v integer
* \return Number of bytes.
*/
unsigned long yasm_size_sleb128(long v);
/** Output integer to buffer in unsigned LEB128-encoded form.
* \param v integer
* \param ptr pointer to storage for output bytes
* \return Number of bytes generated.
*/
unsigned long yasm_get_uleb128(unsigned long v, unsigned char *ptr);
/** Calculate number of bytes unsigned LEB128-encoded form of integer will take.
* \param v integer
* \return Number of bytes.
*/
unsigned long yasm_size_uleb128(unsigned long v);
/** Print an intnum. For debugging purposes.
* \param f file
* \param intn intnum

Loading…
Cancel
Save