]> granicus.if.org Git - yasm/commitdiff
Cut bitvect allocations even more by making a bitvect_from_Dec_static() and
authorPeter Johnson <peter@tortall.net>
Wed, 9 Jan 2002 04:35:51 +0000 (04:35 -0000)
committerPeter Johnson <peter@tortall.net>
Wed, 9 Jan 2002 04:35:51 +0000 (04:35 -0000)
associated _Boot and _Shutdown.

svn path=/trunk/yasm/; revision=435

libyasm/bitvect.c
libyasm/bitvect.h
libyasm/intnum.c
src/bitvect.c
src/bitvect.h
src/intnum.c

index 8dcd7ab882c4e9f13972e61cc704e9ba87e060e9..4c6730b6cc6400ba502f6b149effdcd3fe00806d 100644 (file)
@@ -1606,6 +1606,175 @@ charptr BitVector_to_Dec(wordptr addr)
     return(result);
 }
 
+static wordptr from_Dec_term = NULL;
+static wordptr from_Dec_base = NULL;
+static wordptr from_Dec_prod = NULL;
+static wordptr from_Dec_rank = NULL;
+static wordptr from_Dec_temp = NULL;
+
+ErrCode BitVector_from_Dec_static_Boot(N_word bits)
+{
+    if (bits > 0)
+    {
+       BitVector_from_Dec_static_Shutdown();
+        from_Dec_term = BitVector_Create(BITS,FALSE);
+        if (from_Dec_term == NULL)
+        {
+            return(ErrCode_Null);
+        }
+        from_Dec_base = BitVector_Create(BITS,FALSE);
+        if (from_Dec_base == NULL)
+        {
+            BitVector_Destroy(from_Dec_term);
+            return(ErrCode_Null);
+        }
+        from_Dec_prod = BitVector_Create(bits,FALSE);
+        if (from_Dec_prod == NULL)
+        {
+            BitVector_Destroy(from_Dec_term);
+            BitVector_Destroy(from_Dec_base);
+            return(ErrCode_Null);
+        }
+        from_Dec_rank = BitVector_Create(bits,FALSE);
+        if (from_Dec_rank == NULL)
+        {
+            BitVector_Destroy(from_Dec_term);
+            BitVector_Destroy(from_Dec_base);
+            BitVector_Destroy(from_Dec_prod);
+            return(ErrCode_Null);
+        }
+        from_Dec_temp = BitVector_Create(bits,FALSE);
+        if (from_Dec_temp == NULL)
+        {
+            BitVector_Destroy(from_Dec_term);
+            BitVector_Destroy(from_Dec_base);
+            BitVector_Destroy(from_Dec_prod);
+            BitVector_Destroy(from_Dec_rank);
+            return(ErrCode_Null);
+        }
+    }
+    return(ErrCode_Ok);
+}
+
+void BitVector_from_Dec_static_Shutdown(void)
+{
+    if (from_Dec_term != NULL)
+        BitVector_Destroy(from_Dec_term);
+    if (from_Dec_base != NULL)
+        BitVector_Destroy(from_Dec_base);
+    if (from_Dec_prod != NULL)
+        BitVector_Destroy(from_Dec_prod);
+    if (from_Dec_rank != NULL)
+        BitVector_Destroy(from_Dec_rank);
+    if (from_Dec_temp != NULL)
+        BitVector_Destroy(from_Dec_temp);
+}
+
+ErrCode BitVector_from_Dec_static(wordptr addr, charptr string)
+{
+    ErrCode error = ErrCode_Ok;
+    N_word  bits = bits_(addr);
+    N_word  mask = mask_(addr);
+    boolean init = (bits > BITS);
+    boolean minus;
+    boolean shift;
+    boolean carry;
+    wordptr term = from_Dec_term;
+    wordptr base = from_Dec_base;
+    wordptr prod = from_Dec_prod;
+    wordptr rank = from_Dec_rank;
+    wordptr temp = from_Dec_temp;
+    N_word  accu;
+    N_word  powr;
+    N_word  count;
+    N_word  length;
+    int     digit;
+
+    if (bits > 0)
+    {
+        length = strlen((char *) string);
+        if (length == 0) return(ErrCode_Pars);
+        digit = (int) *string;
+        if ((minus = (digit == (int) '-')) or
+                     (digit == (int) '+'))
+        {
+            string++;
+            if (--length == 0) return(ErrCode_Pars);
+        }
+        string += length;
+       if (init)
+       {
+           BitVector_Empty(prod);
+           BitVector_Empty(rank);
+        }
+        BitVector_Empty(addr);
+        *base = EXP10;
+        shift = FALSE;
+        while ((not error) and (length > 0))
+        {
+            accu = 0;
+            powr = 1;
+            count = LOG10;
+            while ((not error) and (length > 0) and (count-- > 0))
+            {
+                digit = (int) *(--string); length--;
+                /* separate because isdigit() is likely a macro! */
+                if (isdigit(digit) != 0)
+                {
+                    accu += ((N_word) digit - (N_word) '0') * powr;
+                    powr *= 10;
+                }
+                else error = ErrCode_Pars;
+            }
+            if (not error)
+            {
+                if (shift)
+                {
+                    *term = accu;
+                    BitVector_Copy(temp,rank);
+                    error = BitVector_Mul_Pos(prod,temp,term,FALSE);
+                }
+                else
+                {
+                    *prod = accu;
+                    if ((not init) and ((accu AND NOT mask) != 0)) error = ErrCode_Ovfl;
+                }
+                if (not error)
+                {
+                    carry = FALSE;
+                    BitVector_compute(addr,addr,prod,FALSE,&carry);
+                    /* ignores sign change (= overflow) but not */
+                    /* numbers too large (= carry) for resulting bit vector */
+                    if (carry) error = ErrCode_Ovfl;
+                    else
+                    {
+                        if (length > 0)
+                        {
+                            if (shift)
+                            {
+                                BitVector_Copy(temp,rank);
+                                error = BitVector_Mul_Pos(rank,temp,base,FALSE);
+                            }
+                            else
+                            {
+                                *rank = *base;
+                                shift = TRUE;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (not error and minus)
+        {
+            BitVector_Negate(addr,addr);
+            if ((*(addr + size_(addr) - 1) AND mask AND NOT (mask >> 1)) == 0)
+                error = ErrCode_Ovfl;
+        }
+    }
+    return(error);
+}
+
 ErrCode BitVector_from_Dec(wordptr addr, charptr string)
 {
     ErrCode error = ErrCode_Ok;
index 549e0e80bd2a7951d8c88ac354ec9213823b4ea2..f86fdae2dd1a29e5443c762f951ceffc4b9f225b 100644 (file)
@@ -187,6 +187,9 @@ ErrCode BitVector_from_Oct(/*@out@*/ wordptr addr, charptr string);
 ErrCode BitVector_from_Bin(/*@out@*/ wordptr addr, charptr string);
 
 /*@only@*/ charptr BitVector_to_Dec  (wordptr addr);
+ErrCode BitVector_from_Dec_static_Boot(N_word bits);
+void BitVector_from_Dec_static_Shutdown(void);
+ErrCode BitVector_from_Dec_static(/*@out@*/ wordptr addr, charptr string);
 ErrCode BitVector_from_Dec(/*@out@*/ wordptr addr, charptr string);
 
 /*@only@*/ charptr BitVector_to_Enum (wordptr addr);
index ba99f4794502310fe21647bd523b880a6cdf18fd..f91fff981ecd4c67ac2c83c53cf3fdc713d25eae 100644 (file)
@@ -52,6 +52,7 @@ intnum_shutdown(void)
        BitVector_Destroy(conv_bv);
        conv_bv = NULL;
     }
+    BitVector_from_Dec_static_Shutdown();
 }
 
 intnum *
@@ -61,9 +62,12 @@ intnum_new_dec(char *str)
 
     intn->origsize = 0;            /* no reliable way to figure this out */
 
-    if (!conv_bv)
+    if (!conv_bv) {
        conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
-    if (BitVector_from_Dec(conv_bv, (unsigned char *)str) == ErrCode_Ovfl)
+       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
+    }
+    if (BitVector_from_Dec_static(conv_bv,
+                                 (unsigned char *)str) == ErrCode_Ovfl)
        Warning(_("Numeric constant too large for internal format"));
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -86,8 +90,10 @@ intnum_new_bin(char *str)
     if(intn->origsize > BITVECT_ALLOC_SIZE)
        Warning(_("Numeric constant too large for internal format"));
 
-    if (!conv_bv)
+    if (!conv_bv) {
        conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
+    }
     BitVector_from_Bin(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -110,8 +116,10 @@ intnum_new_oct(char *str)
     if(intn->origsize > BITVECT_ALLOC_SIZE)
        Warning(_("Numeric constant too large for internal format"));
 
-    if (!conv_bv)
+    if (!conv_bv) {
        conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
+    }
     BitVector_from_Oct(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -134,8 +142,10 @@ intnum_new_hex(char *str)
     if(intn->origsize > BITVECT_ALLOC_SIZE)
        Warning(_("Numeric constant too large for internal format"));
 
-    if (!conv_bv)
+    if (!conv_bv) {
        conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
+    }
     BitVector_from_Hex(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
index 8dcd7ab882c4e9f13972e61cc704e9ba87e060e9..4c6730b6cc6400ba502f6b149effdcd3fe00806d 100644 (file)
@@ -1606,6 +1606,175 @@ charptr BitVector_to_Dec(wordptr addr)
     return(result);
 }
 
+static wordptr from_Dec_term = NULL;
+static wordptr from_Dec_base = NULL;
+static wordptr from_Dec_prod = NULL;
+static wordptr from_Dec_rank = NULL;
+static wordptr from_Dec_temp = NULL;
+
+ErrCode BitVector_from_Dec_static_Boot(N_word bits)
+{
+    if (bits > 0)
+    {
+       BitVector_from_Dec_static_Shutdown();
+        from_Dec_term = BitVector_Create(BITS,FALSE);
+        if (from_Dec_term == NULL)
+        {
+            return(ErrCode_Null);
+        }
+        from_Dec_base = BitVector_Create(BITS,FALSE);
+        if (from_Dec_base == NULL)
+        {
+            BitVector_Destroy(from_Dec_term);
+            return(ErrCode_Null);
+        }
+        from_Dec_prod = BitVector_Create(bits,FALSE);
+        if (from_Dec_prod == NULL)
+        {
+            BitVector_Destroy(from_Dec_term);
+            BitVector_Destroy(from_Dec_base);
+            return(ErrCode_Null);
+        }
+        from_Dec_rank = BitVector_Create(bits,FALSE);
+        if (from_Dec_rank == NULL)
+        {
+            BitVector_Destroy(from_Dec_term);
+            BitVector_Destroy(from_Dec_base);
+            BitVector_Destroy(from_Dec_prod);
+            return(ErrCode_Null);
+        }
+        from_Dec_temp = BitVector_Create(bits,FALSE);
+        if (from_Dec_temp == NULL)
+        {
+            BitVector_Destroy(from_Dec_term);
+            BitVector_Destroy(from_Dec_base);
+            BitVector_Destroy(from_Dec_prod);
+            BitVector_Destroy(from_Dec_rank);
+            return(ErrCode_Null);
+        }
+    }
+    return(ErrCode_Ok);
+}
+
+void BitVector_from_Dec_static_Shutdown(void)
+{
+    if (from_Dec_term != NULL)
+        BitVector_Destroy(from_Dec_term);
+    if (from_Dec_base != NULL)
+        BitVector_Destroy(from_Dec_base);
+    if (from_Dec_prod != NULL)
+        BitVector_Destroy(from_Dec_prod);
+    if (from_Dec_rank != NULL)
+        BitVector_Destroy(from_Dec_rank);
+    if (from_Dec_temp != NULL)
+        BitVector_Destroy(from_Dec_temp);
+}
+
+ErrCode BitVector_from_Dec_static(wordptr addr, charptr string)
+{
+    ErrCode error = ErrCode_Ok;
+    N_word  bits = bits_(addr);
+    N_word  mask = mask_(addr);
+    boolean init = (bits > BITS);
+    boolean minus;
+    boolean shift;
+    boolean carry;
+    wordptr term = from_Dec_term;
+    wordptr base = from_Dec_base;
+    wordptr prod = from_Dec_prod;
+    wordptr rank = from_Dec_rank;
+    wordptr temp = from_Dec_temp;
+    N_word  accu;
+    N_word  powr;
+    N_word  count;
+    N_word  length;
+    int     digit;
+
+    if (bits > 0)
+    {
+        length = strlen((char *) string);
+        if (length == 0) return(ErrCode_Pars);
+        digit = (int) *string;
+        if ((minus = (digit == (int) '-')) or
+                     (digit == (int) '+'))
+        {
+            string++;
+            if (--length == 0) return(ErrCode_Pars);
+        }
+        string += length;
+       if (init)
+       {
+           BitVector_Empty(prod);
+           BitVector_Empty(rank);
+        }
+        BitVector_Empty(addr);
+        *base = EXP10;
+        shift = FALSE;
+        while ((not error) and (length > 0))
+        {
+            accu = 0;
+            powr = 1;
+            count = LOG10;
+            while ((not error) and (length > 0) and (count-- > 0))
+            {
+                digit = (int) *(--string); length--;
+                /* separate because isdigit() is likely a macro! */
+                if (isdigit(digit) != 0)
+                {
+                    accu += ((N_word) digit - (N_word) '0') * powr;
+                    powr *= 10;
+                }
+                else error = ErrCode_Pars;
+            }
+            if (not error)
+            {
+                if (shift)
+                {
+                    *term = accu;
+                    BitVector_Copy(temp,rank);
+                    error = BitVector_Mul_Pos(prod,temp,term,FALSE);
+                }
+                else
+                {
+                    *prod = accu;
+                    if ((not init) and ((accu AND NOT mask) != 0)) error = ErrCode_Ovfl;
+                }
+                if (not error)
+                {
+                    carry = FALSE;
+                    BitVector_compute(addr,addr,prod,FALSE,&carry);
+                    /* ignores sign change (= overflow) but not */
+                    /* numbers too large (= carry) for resulting bit vector */
+                    if (carry) error = ErrCode_Ovfl;
+                    else
+                    {
+                        if (length > 0)
+                        {
+                            if (shift)
+                            {
+                                BitVector_Copy(temp,rank);
+                                error = BitVector_Mul_Pos(rank,temp,base,FALSE);
+                            }
+                            else
+                            {
+                                *rank = *base;
+                                shift = TRUE;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        if (not error and minus)
+        {
+            BitVector_Negate(addr,addr);
+            if ((*(addr + size_(addr) - 1) AND mask AND NOT (mask >> 1)) == 0)
+                error = ErrCode_Ovfl;
+        }
+    }
+    return(error);
+}
+
 ErrCode BitVector_from_Dec(wordptr addr, charptr string)
 {
     ErrCode error = ErrCode_Ok;
index 549e0e80bd2a7951d8c88ac354ec9213823b4ea2..f86fdae2dd1a29e5443c762f951ceffc4b9f225b 100644 (file)
@@ -187,6 +187,9 @@ ErrCode BitVector_from_Oct(/*@out@*/ wordptr addr, charptr string);
 ErrCode BitVector_from_Bin(/*@out@*/ wordptr addr, charptr string);
 
 /*@only@*/ charptr BitVector_to_Dec  (wordptr addr);
+ErrCode BitVector_from_Dec_static_Boot(N_word bits);
+void BitVector_from_Dec_static_Shutdown(void);
+ErrCode BitVector_from_Dec_static(/*@out@*/ wordptr addr, charptr string);
 ErrCode BitVector_from_Dec(/*@out@*/ wordptr addr, charptr string);
 
 /*@only@*/ charptr BitVector_to_Enum (wordptr addr);
index ba99f4794502310fe21647bd523b880a6cdf18fd..f91fff981ecd4c67ac2c83c53cf3fdc713d25eae 100644 (file)
@@ -52,6 +52,7 @@ intnum_shutdown(void)
        BitVector_Destroy(conv_bv);
        conv_bv = NULL;
     }
+    BitVector_from_Dec_static_Shutdown();
 }
 
 intnum *
@@ -61,9 +62,12 @@ intnum_new_dec(char *str)
 
     intn->origsize = 0;            /* no reliable way to figure this out */
 
-    if (!conv_bv)
+    if (!conv_bv) {
        conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
-    if (BitVector_from_Dec(conv_bv, (unsigned char *)str) == ErrCode_Ovfl)
+       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
+    }
+    if (BitVector_from_Dec_static(conv_bv,
+                                 (unsigned char *)str) == ErrCode_Ovfl)
        Warning(_("Numeric constant too large for internal format"));
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -86,8 +90,10 @@ intnum_new_bin(char *str)
     if(intn->origsize > BITVECT_ALLOC_SIZE)
        Warning(_("Numeric constant too large for internal format"));
 
-    if (!conv_bv)
+    if (!conv_bv) {
        conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
+    }
     BitVector_from_Bin(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -110,8 +116,10 @@ intnum_new_oct(char *str)
     if(intn->origsize > BITVECT_ALLOC_SIZE)
        Warning(_("Numeric constant too large for internal format"));
 
-    if (!conv_bv)
+    if (!conv_bv) {
        conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
+    }
     BitVector_from_Oct(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;
@@ -134,8 +142,10 @@ intnum_new_hex(char *str)
     if(intn->origsize > BITVECT_ALLOC_SIZE)
        Warning(_("Numeric constant too large for internal format"));
 
-    if (!conv_bv)
+    if (!conv_bv) {
        conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+       BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
+    }
     BitVector_from_Hex(conv_bv, (unsigned char *)str);
     if (Set_Max(conv_bv) < 32) {
        intn->type = INTNUM_UL;