Esempio n. 1
0
static unsigned long
get_leb128(wordptr val, unsigned char *ptr, int sign)
{
    unsigned long i, size;
    unsigned char *ptr_orig = ptr;

    if (sign) {
        /* Signed mode */
        if (BitVector_msb_(val)) {
            /* Negative */
            BitVector_Negate(conv_bv, val);
            size = Set_Max(conv_bv)+2;
        } else {
            /* Positive */
            size = Set_Max(val)+2;
        }
    } else {
        /* Unsigned mode */
        size = Set_Max(val)+1;
    }

    /* Positive/Unsigned write */
    for (i=0; i<size; i += 7) {
        *ptr = (unsigned char)BitVector_Chunk_Read(val, 7, i);
        *ptr |= 0x80;
        ptr++;
    }
    *(ptr-1) &= 0x7F;   /* Clear MSB of last byte */
    return (unsigned long)(ptr-ptr_orig);
}
Esempio n. 2
0
/* Compress a bitvector into intnum storage.
 * If saved as a bitvector, clones the passed bitvector.
 * Can modify the passed bitvector.
 */
static void
intnum_frombv(/*@out@*/ yasm_intnum *intn, wordptr bv)
{
    if (Set_Max(bv) < 31) {
        intn->type = INTNUM_L;
        intn->val.l = (long)BitVector_Chunk_Read(bv, 31, 0);
    } else if (BitVector_msb_(bv)) {
        /* Negative, negate and see if we'll fit into a long. */
        unsigned long ul;
        BitVector_Negate(bv, bv);
        if (Set_Max(bv) >= 32 ||
            ((ul = BitVector_Chunk_Read(bv, 32, 0)) & 0x80000000)) {
            /* too negative */
            BitVector_Negate(bv, bv);
            intn->type = INTNUM_BV;
            intn->val.bv = BitVector_Clone(bv);
        } else {
            intn->type = INTNUM_L;
            intn->val.l = -((long)ul);
        }
    } else {
        intn->type = INTNUM_BV;
        intn->val.bv = BitVector_Clone(bv);
    }
}
Esempio n. 3
0
long
yasm_intnum_get_int(const yasm_intnum *intn)
{
    switch (intn->type) {
        case INTNUM_L:
            return intn->val.l;
        case INTNUM_BV:
            if (BitVector_msb_(intn->val.bv)) {
                /* it's negative: negate the bitvector to get a positive
                 * number, then negate the positive number.
                 */
                unsigned long ul;

                BitVector_Negate(conv_bv, intn->val.bv);
                if (Set_Max(conv_bv) >= 32) {
                    /* too negative */
                    return LONG_MIN;
                }
                ul = BitVector_Chunk_Read(conv_bv, 32, 0);
                /* check for too negative */
                return (ul & 0x80000000) ? LONG_MIN : -((long)ul);
            }

            /* it's positive, and since it's a BV, it must be >0x7FFFFFFF */
            return LONG_MAX;
        default:
            yasm_internal_error(N_("unknown intnum type"));
            /*@notreached@*/
            return 0;
    }
}
Esempio n. 4
0
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;
    }
}
Esempio n. 5
0
/* Return 1 if okay size, 0 if not */
int
yasm_intnum_check_size(const yasm_intnum *intn, size_t size, size_t rshift,
                       int rangetype)
{
    wordptr val;

    /* If not already a bitvect, convert value to a bitvect */
    if (intn->type == INTNUM_BV) {
        if (rshift > 0) {
            val = conv_bv;
            BitVector_Copy(val, intn->val.bv);
        } else
            val = intn->val.bv;
    } else
        val = intnum_tobv(conv_bv, intn);

    if (size >= BITVECT_NATIVE_SIZE)
        return 1;

    if (rshift > 0) {
        int carry_in = BitVector_msb_(val);
        while (rshift-- > 0)
            BitVector_shift_right(val, carry_in);
    }

    if (rangetype > 0) {
        if (BitVector_msb_(val)) {
            /* it's negative */
            int retval;

            BitVector_Negate(conv_bv, val);
            BitVector_dec(conv_bv, conv_bv);
            retval = Set_Max(conv_bv) < (long)size-1;

            return retval;
        }
        
        if (rangetype == 1)
            size--;
    }
    return (Set_Max(val) < (long)size);
}
Esempio n. 6
0
static void
floatnum_normalize(yasm_floatnum *flt)
{
    long norm_amt;

    if (BitVector_is_empty(flt->mantissa)) {
        flt->exponent = 0;
        return;
    }

    /* Look for the highest set bit, shift to make it the MSB, and adjust
     * exponent.  Don't let exponent go negative. */
    norm_amt = (MANT_BITS-1)-Set_Max(flt->mantissa);
    if (norm_amt > (long)flt->exponent)
        norm_amt = (long)flt->exponent;
    BitVector_Move_Left(flt->mantissa, (N_int)norm_amt);
    flt->exponent -= (unsigned short)norm_amt;
}
Esempio n. 7
0
unsigned long
yasm_intnum_get_uint(const yasm_intnum *intn)
{
    switch (intn->type) {
        case INTNUM_L:
            if (intn->val.l < 0)
                return 0;
            return (unsigned long)intn->val.l;
        case INTNUM_BV:
            if (BitVector_msb_(intn->val.bv))
                return 0;
            if (Set_Max(intn->val.bv) > 32)
                return ULONG_MAX;
            return BitVector_Chunk_Read(intn->val.bv, 32, 0);
        default:
            yasm_internal_error(N_("unknown intnum type"));
            /*@notreached@*/
            return 0;
    }
}
Esempio n. 8
0
/* acc *= op */
static void
floatnum_mul(yasm_floatnum *acc, const yasm_floatnum *op)
{
    long expon;
    wordptr product, op1, op2;
    long norm_amt;

    /* Compute the new sign */
    acc->sign ^= op->sign;

    /* Check for multiply by 0 */
    if (BitVector_is_empty(acc->mantissa) || BitVector_is_empty(op->mantissa)) {
        BitVector_Empty(acc->mantissa);
        acc->exponent = EXP_ZERO;
        return;
    }

    /* Add exponents, checking for overflow/underflow. */
    expon = (((int)acc->exponent)-EXP_BIAS) + (((int)op->exponent)-EXP_BIAS);
    expon += EXP_BIAS;
    if (expon > EXP_MAX) {
        /* Overflow; return infinity. */
        BitVector_Empty(acc->mantissa);
        acc->exponent = EXP_INF;
        return;
    } else if (expon < EXP_MIN) {
        /* Underflow; return zero. */
        BitVector_Empty(acc->mantissa);
        acc->exponent = EXP_ZERO;
        return;
    }

    /* Add one to the final exponent, as the multiply shifts one extra time. */
    acc->exponent = (unsigned short)(expon+1);

    /* Allocate space for the multiply result */
    product = BitVector_Create((N_int)((MANT_BITS+1)*2), FALSE);

    /* Allocate 1-bit-longer fields to force the operands to be unsigned */
    op1 = BitVector_Create((N_int)(MANT_BITS+1), FALSE);
    op2 = BitVector_Create((N_int)(MANT_BITS+1), FALSE);

    /* Make the operands unsigned after copying from original operands */
    BitVector_Copy(op1, acc->mantissa);
    BitVector_MSB(op1, 0);
    BitVector_Copy(op2, op->mantissa);
    BitVector_MSB(op2, 0);

    /* Compute the product of the mantissas */
    BitVector_Multiply(product, op1, op2);

    /* Normalize the product.  Note: we know the product is non-zero because
     * both of the original operands were non-zero.
     *
     * Look for the highest set bit, shift to make it the MSB, and adjust
     * exponent.  Don't let exponent go negative.
     */
    norm_amt = (MANT_BITS*2-1)-Set_Max(product);
    if (norm_amt > (long)acc->exponent)
        norm_amt = (long)acc->exponent;
    BitVector_Move_Left(product, (N_int)norm_amt);
    acc->exponent -= (unsigned short)norm_amt;

    /* Store the highest bits of the result */
    BitVector_Interval_Copy(acc->mantissa, product, 0, MANT_BITS, MANT_BITS);

    /* Free allocated variables */
    BitVector_Destroy(product);
    BitVector_Destroy(op1);
    BitVector_Destroy(op2);
}