/*
 * 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: intnum.c,v 1.1.1.1 2012/03/29 17:21:04 uid42307 Exp $");

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