/*
 * Integer number functions.
 *
 *  Copyright (C) 2001-2007  Peter Johnson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include "util.h"
/*@unused@*/ RCSID("$Id$");

#include <ctype.h>
#include <limits.h>

#include "coretype.h"
#include "bitvect.h"
#include "file.h"

#include "errwarn.h"
#include "intnum.h"


/* "Native" "word" size for intnum calculations. */
#define BITVECT_NATIVE_SIZE     256

struct yasm_intnum {
    union val {
        long l;                 /* integer value (for integers <32 bits) */
        wordptr bv;             /* bit vector (for integers >=32 bits) */
    } val;
    enum { INTNUM_L, INTNUM_BV } type;
};

/* static bitvect used for conversions */
static /*@only@*/ wordptr conv_bv;

/* static bitvects used for computation */
static /*@only@*/ wordptr result, spare, op1static, op2static;

static /*@only@*/ BitVector_from_Dec_static_data *from_dec_data;


void
yasm_intnum_initialize(void)
{
    conv_bv = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
    result = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
    spare = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
    op1static = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
    op2static = BitVector_Create(BITVECT_NATIVE_SIZE, FALSE);
    from_dec_data = BitVector_from_Dec_static_Boot(BITVECT_NATIVE_SIZE);
}

void
yasm_intnum_cleanup(void)
{
    BitVector_from_Dec_static_Shutdown(from_dec_data);
    BitVector_Destroy(op2static);
    BitVector_Destroy(op1static);
    BitVector_Destroy(spare);
    BitVector_Destroy(result);
    BitVector_Destroy(conv_bv);
}

/* 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);
    }
}

/* If intnum is a BV, returns its bitvector directly.
 * If not, converts into passed bv and returns that instead.
 */
static wordptr
intnum_tobv(/*@returned@*/ wordptr bv, const yasm_intnum *intn)
{
    if (intn->type == INTNUM_BV)
        return intn->val.bv;

    BitVector_Empty(bv);
    if (intn->val.l >= 0)
        BitVector_Chunk_Store(bv, 32, 0, (unsigned long)intn->val.l);
    else {
        BitVector_Chunk_Store(bv, 32, 0, (unsigned long)-intn->val.l);
        BitVector_Negate(bv, bv);
    }
    return bv;
}

yasm_intnum *
yasm_intnum_create_dec(char *str)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));

    switch (BitVector_from_Dec_static(from_dec_data, conv_bv,
                                      (unsigned char *)str)) {
        case ErrCode_Pars:
            yasm_error_set(YASM_ERROR_VALUE, N_("invalid decimal literal"));
            break;
        case ErrCode_Ovfl:
            yasm_error_set(YASM_ERROR_OVERFLOW,
                N_("Numeric constant too large for internal format"));
            break;
        default:
            break;
    }
    intnum_frombv(intn, conv_bv);
    return intn;
}

yasm_intnum *
yasm_intnum_create_bin(char *str)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));

    switch (BitVector_from_Bin(conv_bv, (unsigned char *)str)) {
        case ErrCode_Pars:
            yasm_error_set(YASM_ERROR_VALUE, N_("invalid binary literal"));
            break;
        case ErrCode_Ovfl:
            yasm_error_set(YASM_ERROR_OVERFLOW,
                N_("Numeric constant too large for internal format"));
            break;
        default:
            break;
    }
    intnum_frombv(intn, conv_bv);
    return intn;
}

yasm_intnum *
yasm_intnum_create_oct(char *str)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));

    switch (BitVector_from_Oct(conv_bv, (unsigned char *)str)) {
        case ErrCode_Pars:
            yasm_error_set(YASM_ERROR_VALUE, N_("invalid octal literal"));
            break;
        case ErrCode_Ovfl:
            yasm_error_set(YASM_ERROR_OVERFLOW,
                N_("Numeric constant too large for internal format"));
            break;
        default:
            break;
    }
    intnum_frombv(intn, conv_bv);
    return intn;
}

yasm_intnum *
yasm_intnum_create_hex(char *str)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));

    switch (BitVector_from_Hex(conv_bv, (unsigned char *)str)) {
        case ErrCode_Pars:
            yasm_error_set(YASM_ERROR_VALUE, N_("invalid hex literal"));
            break;
        case ErrCode_Ovfl:
            yasm_error_set(YASM_ERROR_OVERFLOW,
                           N_("Numeric constant too large for internal format"));
            break;
        default:
            break;
    }
    intnum_frombv(intn, conv_bv);
    return intn;
}

/*@-usedef -compdef -uniondef@*/
yasm_intnum *
yasm_intnum_create_charconst_nasm(const char *str)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
    size_t len = strlen(str);

    if(len*8 > BITVECT_NATIVE_SIZE)
        yasm_error_set(YASM_ERROR_OVERFLOW,
                       N_("Character constant too large for internal format"));

    /* be conservative in choosing bitvect in case MSB is set */
    if (len > 3) {
        BitVector_Empty(conv_bv);
        intn->type = INTNUM_BV;
    } else {
        intn->val.l = 0;
        intn->type = INTNUM_L;
    }

    switch (len) {
        case 3:
            intn->val.l |= ((unsigned long)str[2]) & 0xff;
            intn->val.l <<= 8;
            /*@fallthrough@*/
        case 2:
            intn->val.l |= ((unsigned long)str[1]) & 0xff;
            intn->val.l <<= 8;
            /*@fallthrough@*/
        case 1:
            intn->val.l |= ((unsigned long)str[0]) & 0xff;
        case 0:
            break;
        default:
            /* >=32 bit conversion */
            while (len) {
                BitVector_Move_Left(conv_bv, 8);
                BitVector_Chunk_Store(conv_bv, 8, 0,
                                      ((unsigned long)str[--len]) & 0xff);
            }
            intn->val.bv = BitVector_Clone(conv_bv);
    }

    return intn;
}

yasm_intnum *
yasm_intnum_create_charconst_tasm(const char *str)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
    size_t len = strlen(str);
    size_t i;

    if(len*8 > BITVECT_NATIVE_SIZE)
        yasm_error_set(YASM_ERROR_OVERFLOW,
                       N_("Character constant too large for internal format"));

    /* be conservative in choosing bitvect in case MSB is set */
    if (len > 3) {
        BitVector_Empty(conv_bv);
        intn->type = INTNUM_BV;
    } else {
        intn->val.l = 0;
        intn->type = INTNUM_L;
    }

    /* tasm uses big endian notation */
    i = 0;
    switch (len) {
        case 3:
            intn->val.l |= ((unsigned long)str[i++]) & 0xff;
            intn->val.l <<= 8;
            /*@fallthrough@*/
        case 2:
            intn->val.l |= ((unsigned long)str[i++]) & 0xff;
            intn->val.l <<= 8;
            /*@fallthrough@*/
        case 1:
            intn->val.l |= ((unsigned long)str[i++]) & 0xff;
        case 0:
            break;
        default:
            /* >=32 bit conversion */
            while (i < len) {
                BitVector_Chunk_Store(conv_bv, 8, (len-i-1)*8,
                                      ((unsigned long)str[i]) & 0xff);
                i++;
            }
            intn->val.bv = BitVector_Clone(conv_bv);
    }

    return intn;
}
/*@=usedef =compdef =uniondef@*/

yasm_intnum *
yasm_intnum_create_uint(unsigned long i)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));

    if (i > LONG_MAX) {
        /* Too big, store as bitvector */
        intn->val.bv = BitVector_Create(BITVECT_NATIVE_SIZE, TRUE);
        intn->type = INTNUM_BV;
        BitVector_Chunk_Store(intn->val.bv, 32, 0, i);
    } else {
        intn->val.l = (long)i;
        intn->type = INTNUM_L;
    }

    return intn;
}

yasm_intnum *
yasm_intnum_create_int(long i)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));

    intn->val.l = i;
    intn->type = INTNUM_L;

    return intn;
}

yasm_intnum *
yasm_intnum_create_leb128(const unsigned char *ptr, int sign,
                          unsigned long *size)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
    const unsigned char *ptr_orig = ptr;
    unsigned long i = 0;

    BitVector_Empty(conv_bv);
    for (;;) {
        BitVector_Chunk_Store(conv_bv, 7, i, *ptr);
        i += 7;
        if ((*ptr & 0x80) != 0x80)
            break;
        ptr++;
    }

    *size = (unsigned long)(ptr-ptr_orig)+1;

    if(i > BITVECT_NATIVE_SIZE)
        yasm_error_set(YASM_ERROR_OVERFLOW,
                       N_("Numeric constant too large for internal format"));
    else if (sign && (*ptr & 0x40) == 0x40)
        BitVector_Interval_Fill(conv_bv, i, BITVECT_NATIVE_SIZE-1);

    intnum_frombv(intn, conv_bv);
    return intn;
}

yasm_intnum *
yasm_intnum_create_sized(unsigned char *ptr, int sign, size_t srcsize,
                         int bigendian)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
    unsigned long i = 0;

    if (srcsize*8 > BITVECT_NATIVE_SIZE)
        yasm_error_set(YASM_ERROR_OVERFLOW,
                       N_("Numeric constant too large for internal format"));

    /* Read the buffer into a bitvect */
    BitVector_Empty(conv_bv);
    if (bigendian) {
        /* TODO */
        yasm_internal_error(N_("big endian not implemented"));
    } else {
        for (i = 0; i < srcsize; i++)
            BitVector_Chunk_Store(conv_bv, 8, i*8, ptr[i]);
    }

    /* Sign extend if needed */
    if (srcsize*8 < BITVECT_NATIVE_SIZE && sign && (ptr[i] & 0x80) == 0x80)
        BitVector_Interval_Fill(conv_bv, i*8, BITVECT_NATIVE_SIZE-1);

    intnum_frombv(intn, conv_bv);
    return intn;
}

yasm_intnum *
yasm_intnum_copy(const yasm_intnum *intn)
{
    yasm_intnum *n = yasm_xmalloc(sizeof(yasm_intnum));

    switch (intn->type) {
        case INTNUM_L:
            n->val.l = intn->val.l;
            break;
        case INTNUM_BV:
            n->val.bv = BitVector_Clone(intn->val.bv);
            break;
    }
    n->type = intn->type;

    return n;
}

void
yasm_intnum_destroy(yasm_intnum *intn)
{
    if (intn->type == INTNUM_BV)
        BitVector_Destroy(intn->val.bv);
    yasm_xfree(intn);
}

/*@-nullderef -nullpass -branchstate@*/
int
yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand)
{
    boolean carry = 0;
    wordptr op1, op2 = NULL;
    N_int count;

    /* Always do computations with in full bit vector.
     * Bit vector results must be calculated through intermediate storage.
     */
    op1 = intnum_tobv(op1static, acc);
    if (operand)
        op2 = intnum_tobv(op2static, operand);

    if (!operand && op != YASM_EXPR_NEG && op != YASM_EXPR_NOT &&
        op != YASM_EXPR_LNOT) {
        yasm_error_set(YASM_ERROR_ARITHMETIC,
                       N_("operation needs an operand"));
        BitVector_Empty(result);
        return 1;
    }

    /* A operation does a bitvector computation if result is allocated. */
    switch (op) {
        case YASM_EXPR_ADD:
            BitVector_add(result, op1, op2, &carry);
            break;
        case YASM_EXPR_SUB:
            BitVector_sub(result, op1, op2, &carry);
            break;
        case YASM_EXPR_MUL:
            BitVector_Multiply(result, op1, op2);
            break;
        case YASM_EXPR_DIV:
            /* TODO: make sure op1 and op2 are unsigned */
            if (BitVector_is_empty(op2)) {
                yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
                BitVector_Empty(result);
                return 1;
            } else
                BitVector_Divide(result, op1, op2, spare);
            break;
        case YASM_EXPR_SIGNDIV:
            if (BitVector_is_empty(op2)) {
                yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
                BitVector_Empty(result);
                return 1;
            } else
                BitVector_Divide(result, op1, op2, spare);
            break;
        case YASM_EXPR_MOD:
            /* TODO: make sure op1 and op2 are unsigned */
            if (BitVector_is_empty(op2)) {
                yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
                BitVector_Empty(result);
                return 1;
            } else
                BitVector_Divide(spare, op1, op2, result);
            break;
        case YASM_EXPR_SIGNMOD:
            if (BitVector_is_empty(op2)) {
                yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero"));
                BitVector_Empty(result);
                return 1;
            } else
                BitVector_Divide(spare, op1, op2, result);
            break;
        case YASM_EXPR_NEG:
            BitVector_Negate(result, op1);
            break;
        case YASM_EXPR_NOT:
            Set_Complement(result, op1);
            break;
        case YASM_EXPR_OR:
            Set_Union(result, op1, op2);
            break;
        case YASM_EXPR_AND:
            Set_Intersection(result, op1, op2);
            break;
        case YASM_EXPR_XOR:
            Set_ExclusiveOr(result, op1, op2);
            break;
        case YASM_EXPR_XNOR:
            Set_ExclusiveOr(result, op1, op2);
            Set_Complement(result, result);
            break;
        case YASM_EXPR_NOR:
            Set_Union(result, op1, op2);
            Set_Complement(result, result);
            break;
        case YASM_EXPR_SHL:
            if (operand->type == INTNUM_L && operand->val.l >= 0) {
                BitVector_Copy(result, op1);
                BitVector_Move_Left(result, (N_int)operand->val.l);
            } else      /* don't even bother, just zero result */
                BitVector_Empty(result);
            break;
        case YASM_EXPR_SHR:
            if (operand->type == INTNUM_L && operand->val.l >= 0) {
                BitVector_Copy(result, op1);
                carry = BitVector_msb_(op1);
                count = (N_int)operand->val.l;
                while (count-- > 0)
                    BitVector_shift_right(result, carry);
            } else      /* don't even bother, just zero result */
                BitVector_Empty(result);
            break;
        case YASM_EXPR_LOR:
            BitVector_Empty(result);
            BitVector_LSB(result, !BitVector_is_empty(op1) ||
                          !BitVector_is_empty(op2));
            break;
        case YASM_EXPR_LAND:
            BitVector_Empty(result);
            BitVector_LSB(result, !BitVector_is_empty(op1) &&
                          !BitVector_is_empty(op2));
            break;
        case YASM_EXPR_LNOT:
            BitVector_Empty(result);
            BitVector_LSB(result, BitVector_is_empty(op1));
            break;
        case YASM_EXPR_LXOR:
            BitVector_Empty(result);
            BitVector_LSB(result, !BitVector_is_empty(op1) ^
                          !BitVector_is_empty(op2));
            break;
        case YASM_EXPR_LXNOR:
            BitVector_Empty(result);
            BitVector_LSB(result, !(!BitVector_is_empty(op1) ^
                          !BitVector_is_empty(op2)));
            break;
        case YASM_EXPR_LNOR:
            BitVector_Empty(result);
            BitVector_LSB(result, !(!BitVector_is_empty(op1) ||
                          !BitVector_is_empty(op2)));
            break;
        case YASM_EXPR_EQ:
            BitVector_Empty(result);
            BitVector_LSB(result, BitVector_equal(op1, op2));
            break;
        case YASM_EXPR_LT:
            BitVector_Empty(result);
            BitVector_LSB(result, BitVector_Compare(op1, op2) < 0);
            break;
        case YASM_EXPR_GT:
            BitVector_Empty(result);
            BitVector_LSB(result, BitVector_Compare(op1, op2) > 0);
            break;
        case YASM_EXPR_LE:
            BitVector_Empty(result);
            BitVector_LSB(result, BitVector_Compare(op1, op2) <= 0);
            break;
        case YASM_EXPR_GE:
            BitVector_Empty(result);
            BitVector_LSB(result, BitVector_Compare(op1, op2) >= 0);
            break;
        case YASM_EXPR_NE:
            BitVector_Empty(result);
            BitVector_LSB(result, !BitVector_equal(op1, op2));
            break;
        case YASM_EXPR_SEG:
            yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
                           "SEG");
            break;
        case YASM_EXPR_WRT:
            yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
                           "WRT");
            break;
        case YASM_EXPR_SEGOFF:
            yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"),
                           ":");
            break;
        case YASM_EXPR_IDENT:
            if (result)
                BitVector_Copy(result, op1);
            break;
        default:
            yasm_error_set(YASM_ERROR_ARITHMETIC,
                           N_("invalid operation in intnum calculation"));
            BitVector_Empty(result);
            return 1;
    }

    /* Try to fit the result into 32 bits if possible */
    if (acc->type == INTNUM_BV)
        BitVector_Destroy(acc->val.bv);
    intnum_frombv(acc, result);
    return 0;
}
/*@=nullderef =nullpass =branchstate@*/

int
yasm_intnum_compare(const yasm_intnum *intn1, const yasm_intnum *intn2)
{
    wordptr op1, op2;

    if (intn1->type == INTNUM_L && intn2->type == INTNUM_L) {
        if (intn1->val.l < intn2->val.l)
            return -1;
        if (intn1->val.l > intn2->val.l)
            return 1;
        return 0;
    }

    op1 = intnum_tobv(op1static, intn1);
    op2 = intnum_tobv(op2static, intn2);
    return BitVector_Compare(op1, op2);
}

void
yasm_intnum_zero(yasm_intnum *intn)
{
    yasm_intnum_set_int(intn, 0);
}

void
yasm_intnum_set(yasm_intnum *intn, const yasm_intnum *val)
{
    if (intn->type == val->type) {
        switch (val->type) {
            case INTNUM_L:
                intn->val.l = val->val.l;
                break;
            case INTNUM_BV:
                BitVector_Copy(intn->val.bv, val->val.bv);
                break;
        }
    } else {
        switch (val->type) {
            case INTNUM_L:
                BitVector_Destroy(intn->val.bv);
                intn->val.l = val->val.l;
                break;
            case INTNUM_BV:
                intn->val.bv = BitVector_Clone(val->val.bv);
                break;
        }
        intn->type = val->type;
    }
}

void
yasm_intnum_set_uint(yasm_intnum *intn, unsigned long val)
{
    if (val > LONG_MAX) {
        if (intn->type != INTNUM_BV) {
            intn->val.bv = BitVector_Create(BITVECT_NATIVE_SIZE, TRUE);
            intn->type = INTNUM_BV;
        }
        BitVector_Chunk_Store(intn->val.bv, 32, 0, val);
    } else {
        if (intn->type == INTNUM_BV) {
            BitVector_Destroy(intn->val.bv);
            intn->type = INTNUM_L;
        }
        intn->val.l = (long)val;
    }
}

void
yasm_intnum_set_int(yasm_intnum *intn, long val)
{
    if (intn->type == INTNUM_BV)
        BitVector_Destroy(intn->val.bv);
    intn->type = INTNUM_L;
    intn->val.l = val;
}

int
yasm_intnum_is_zero(const yasm_intnum *intn)
{
    return (intn->type == INTNUM_L && intn->val.l == 0);
}

int
yasm_intnum_is_pos1(const yasm_intnum *intn)
{
    return (intn->type == INTNUM_L && intn->val.l == 1);
}

int
yasm_intnum_is_neg1(const yasm_intnum *intn)
{
    return (intn->type == INTNUM_L && intn->val.l == -1);
}

int
yasm_intnum_sign(const yasm_intnum *intn)
{
    if (intn->type == INTNUM_L) {
        if (intn->val.l == 0)
            return 0;
        else if (intn->val.l < 0)
            return -1;
        else
            return 1;
    } else
        return BitVector_Sign(intn->val.bv);
}

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

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

void
yasm_intnum_get_sized(const yasm_intnum *intn, unsigned char *ptr,
                      size_t destsize, size_t valsize, int shift,
                      int bigendian, int warn)
{
    wordptr op1 = op1static, op2;
    unsigned char *buf;
    unsigned int len;
    size_t rshift = shift < 0 ? (size_t)(-shift) : 0;
    int carry_in;

    /* Currently don't support destinations larger than our native size */
    if (destsize*8 > BITVECT_NATIVE_SIZE)
        yasm_internal_error(N_("destination too large"));

    /* General size warnings */
    if (warn<0 && !yasm_intnum_check_size(intn, valsize, rshift, 1))
        yasm_warn_set(YASM_WARN_GENERAL,
                      N_("value does not fit in signed %d bit field"),
                      valsize);
    if (warn>0 && !yasm_intnum_check_size(intn, valsize, rshift, 2))
        yasm_warn_set(YASM_WARN_GENERAL,
                      N_("value does not fit in %d bit field"), valsize);

    /* Read the original data into a bitvect */
    if (bigendian) {
        /* TODO */
        yasm_internal_error(N_("big endian not implemented"));
    } else
        BitVector_Block_Store(op1, ptr, (N_int)destsize);

    /* If not already a bitvect, convert value to be written to a bitvect */
    op2 = intnum_tobv(op2static, intn);

    /* Check low bits if right shifting and warnings enabled */
    if (warn && rshift > 0) {
        BitVector_Copy(conv_bv, op2);
        BitVector_Move_Left(conv_bv, (N_int)(BITVECT_NATIVE_SIZE-rshift));
        if (!BitVector_is_empty(conv_bv))
            yasm_warn_set(YASM_WARN_GENERAL,
                          N_("misaligned value, truncating to boundary"));
    }

    /* Shift right if needed */
    if (rshift > 0) {
        carry_in = BitVector_msb_(op2);
        while (rshift-- > 0)
            BitVector_shift_right(op2, carry_in);
        shift = 0;
    }

    /* Write the new value into the destination bitvect */
    BitVector_Interval_Copy(op1, op2, (unsigned int)shift, 0, (N_int)valsize);

    /* Write out the new data */
    buf = BitVector_Block_Read(op1, &len);
    if (bigendian) {
        /* TODO */
        yasm_internal_error(N_("big endian not implemented"));
    } else
        memcpy(ptr, buf, destsize);
    yasm_xfree(buf);
}

/* 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);
}

int
yasm_intnum_in_range(const yasm_intnum *intn, long low, long high)
{
    wordptr val = intnum_tobv(result, intn);
    wordptr lval = op1static;
    wordptr hval = op2static;

    /* Convert high and low to bitvects */
    BitVector_Empty(lval);
    if (low >= 0)
        BitVector_Chunk_Store(lval, 32, 0, (unsigned long)low);
    else {
        BitVector_Chunk_Store(lval, 32, 0, (unsigned long)(-low));
        BitVector_Negate(lval, lval);
    }

    BitVector_Empty(hval);
    if (high >= 0)
        BitVector_Chunk_Store(hval, 32, 0, (unsigned long)high);
    else {
        BitVector_Chunk_Store(hval, 32, 0, (unsigned long)(-high));
        BitVector_Negate(hval, hval);
    }

    /* Compare! */
    return (BitVector_Compare(val, lval) >= 0
            && BitVector_Compare(val, hval) <= 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);
}

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;

    /* Shortcut 0 */
    if (intn->type == INTNUM_L && intn->val.l == 0) {
        *ptr = 0;
        return 1;
    }

    /* If not already a bitvect, convert value to be written to a bitvect */
    val = intnum_tobv(op1static, intn);

    return get_leb128(val, ptr, sign);
}

unsigned long
yasm_intnum_size_leb128(const yasm_intnum *intn, int sign)
{
    wordptr val;

    /* Shortcut 0 */
    if (intn->type == INTNUM_L && intn->val.l == 0) {
        return 1;
    }

    /* If not already a bitvect, convert value to a bitvect */
    val = intnum_tobv(op1static, intn);

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

char *
yasm_intnum_get_str(const yasm_intnum *intn)
{
    unsigned char *s;

    switch (intn->type) {
        case INTNUM_L:
            s = yasm_xmalloc(16);
            sprintf((char *)s, "%ld", intn->val.l);
            return (char *)s;
            break;
        case INTNUM_BV:
            return (char *)BitVector_to_Dec(intn->val.bv);
            break;
    }
    /*@notreached@*/
    return NULL;
}

void
yasm_intnum_print(const yasm_intnum *intn, FILE *f)
{
    unsigned char *s;

    switch (intn->type) {
        case INTNUM_L:
            fprintf(f, "0x%lx", intn->val.l);
            break;
        case INTNUM_BV:
            s = BitVector_to_Hex(intn->val.bv);
            fprintf(f, "0x%s", (char *)s);
            yasm_xfree(s);
            break;
    }
}
