]> granicus.if.org Git - yasm/commitdiff
* intnum.h (yasm_get_sleb128, yasm_size_sleb128): New functions to handle
authorPeter Johnson <peter@tortall.net>
Thu, 9 Feb 2006 05:00:09 +0000 (05:00 -0000)
committerPeter Johnson <peter@tortall.net>
Thu, 9 Feb 2006 05:00:09 +0000 (05:00 -0000)
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

libyasm/intnum.c
libyasm/intnum.h

index 6544a86d0dfc457663b738a248ce5133e564de20..6329f41eca524075e106c76d17d281306d3a762c 100644 (file)
@@ -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
index 645047e3036495f3c037db371667407dd7c217c0..e05ac1c8fa444861beb7f1550f8b13a8f030e4b0 100644 (file)
@@ -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