/*
 * Integer number functions.
 *
 *  Copyright (C) 2001  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.
 */
#define YASM_LIB_INTERNAL
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");

#include <ctype.h>

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

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


#define BITVECT_ALLOC_SIZE	80

struct yasm_intnum {
    union val {
	unsigned long ul;	/* integer value (for integers <=32 bits) */
	intptr bv;		/* bit vector (for integers >32 bits) */
    } val;
    enum { INTNUM_UL, INTNUM_BV } type;
    unsigned char origsize;	/* original (parsed) size, in bits */
};

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


void
yasm_intnum_initialize(void)
{
    conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
    BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE);
}

void
yasm_intnum_cleanup(void)
{
    BitVector_Destroy(conv_bv);
    BitVector_from_Dec_static_Shutdown();
}

yasm_intnum *
yasm_intnum_new_dec(char *str, unsigned long lindex)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));

    intn->origsize = 0;	    /* no reliable way to figure this out */

    if (BitVector_from_Dec_static(conv_bv,
				  (unsigned char *)str) == ErrCode_Ovfl)
	yasm__warning(YASM_WARN_GENERAL, lindex,
		      N_("Numeric constant too large for internal format"));
    if (Set_Max(conv_bv) < 32) {
	intn->type = INTNUM_UL;
	intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
    } else {
	intn->type = INTNUM_BV;
	intn->val.bv = BitVector_Clone(conv_bv);
    }

    return intn;
}

yasm_intnum *
yasm_intnum_new_bin(char *str, unsigned long lindex)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));

    intn->origsize = (unsigned char)strlen(str);

    if(intn->origsize > BITVECT_ALLOC_SIZE)
	yasm__warning(YASM_WARN_GENERAL, lindex,
		      N_("Numeric constant too large for internal format"));

    BitVector_from_Bin(conv_bv, (unsigned char *)str);
    if (Set_Max(conv_bv) < 32) {
	intn->type = INTNUM_UL;
	intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
    } else {
	intn->type = INTNUM_BV;
	intn->val.bv = BitVector_Clone(conv_bv);
    }

    return intn;
}

yasm_intnum *
yasm_intnum_new_oct(char *str, unsigned long lindex)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));

    intn->origsize = strlen(str)*3;

    if(intn->origsize > BITVECT_ALLOC_SIZE)
	yasm__warning(YASM_WARN_GENERAL, lindex,
		      N_("Numeric constant too large for internal format"));

    BitVector_from_Oct(conv_bv, (unsigned char *)str);
    if (Set_Max(conv_bv) < 32) {
	intn->type = INTNUM_UL;
	intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
    } else {
	intn->type = INTNUM_BV;
	intn->val.bv = BitVector_Clone(conv_bv);
    }

    return intn;
}

yasm_intnum *
yasm_intnum_new_hex(char *str, unsigned long lindex)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));

    intn->origsize = strlen(str)*4;

    if(intn->origsize > BITVECT_ALLOC_SIZE)
	yasm__warning(YASM_WARN_GENERAL, lindex,
		      N_("Numeric constant too large for internal format"));

    BitVector_from_Hex(conv_bv, (unsigned char *)str);
    if (Set_Max(conv_bv) < 32) {
	intn->type = INTNUM_UL;
	intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0);
    } else {
	intn->type = INTNUM_BV;
	intn->val.bv = BitVector_Clone(conv_bv);
    }

    return intn;
}

/*@-usedef -compdef -uniondef@*/
yasm_intnum *
yasm_intnum_new_charconst_nasm(const char *str, unsigned long lindex)
{
    yasm_intnum *intn = yasm_xmalloc(sizeof(yasm_intnum));
    size_t len = strlen(str);

    if (len > 4)
	yasm__warning(YASM_WARN_GENERAL, lindex,
	    N_("character constant too large, ignoring trailing characters"));

    intn->val.ul = 0;
    intn->type = INTNUM_UL;
    intn->origsize = len*8;

    switch (len) {
	case 4:
	    intn->val.ul |= (unsigned long)str[3];
	    intn->val.ul <<= 8;
	    /*@fallthrough@*/
	case 3:
	    intn->val.ul |= (unsigned long)str[2];
	    intn->val.ul <<= 8;
	    /*@fallthrough@*/
	case 2:
	    intn->val.ul |= (unsigned long)str[1];
	    intn->val.ul <<= 8;
	    /*@fallthrough@*/
	case 1:
	    intn->val.ul |= (unsigned long)str[0];
    }

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

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

    intn->val.ul = i;
    intn->type = INTNUM_UL;
    intn->origsize = 0;

    return intn;
}

yasm_intnum *
yasm_intnum_new_int(long i)
{
    /* FIXME: Better way of handling signed numbers? */
    return yasm_intnum_new_uint((unsigned long)i);
}

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

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

    return n;
}

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

/*@-nullderef -nullpass -branchstate@*/
void
yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand,
		 unsigned long lindex)
{
    wordptr result = (wordptr)NULL, op1 = (wordptr)NULL, op2 = (wordptr)NULL;
    wordptr spare = (wordptr)NULL;
    boolean carry;

    /* upsize to bitvector op if one of two parameters is bitvector already.
     * BitVector results must be calculated through intermediate storage.
     */
    if (acc->type == INTNUM_BV || (operand && operand->type == INTNUM_BV)) {
	result = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
	spare = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);

	if (acc->type == INTNUM_BV)
	    op1 = acc->val.bv;
	else {
	    op1 = BitVector_Create(BITVECT_ALLOC_SIZE, TRUE);
	    BitVector_Chunk_Store(op1, 32, 0, acc->val.ul);
	}

	if (operand) {
	    if (operand->type == INTNUM_BV)
		op2 = acc->val.bv;
	    else {
		op2 = BitVector_Create(BITVECT_ALLOC_SIZE, TRUE);
		BitVector_Chunk_Store(op2, 32, 0, operand->val.ul);
	    }
	}
    }

    if (!operand && op != YASM_EXPR_NEG && op != YASM_EXPR_NOT &&
	op != YASM_EXPR_LNOT)
	yasm_internal_error(N_("Operation needs an operand"));

    /* A operation does a bitvector computation if result is allocated. */
    switch (op) {
	case YASM_EXPR_ADD:
	    if (result)
		BitVector_add(result, op1, op2, &carry);
	    else
		acc->val.ul = acc->val.ul + operand->val.ul;
	    break;
	case YASM_EXPR_SUB:
	    if (result)
		BitVector_sub(result, op1, op2, &carry);
	    else
		acc->val.ul = acc->val.ul - operand->val.ul;
	    break;
	case YASM_EXPR_MUL:
	    if (result)
		/* TODO: Make sure result size = op1+op2 */
		BitVector_Multiply(result, op1, op2);
	    else
		acc->val.ul = acc->val.ul * operand->val.ul;
	    break;
	case YASM_EXPR_DIV:
	    if (result) {
		/* TODO: make sure op1 and op2 are unsigned */
		BitVector_Divide(result, op1, op2, spare);
	    } else
		acc->val.ul = acc->val.ul / operand->val.ul;
	    break;
	case YASM_EXPR_SIGNDIV:
	    if (result)
		BitVector_Divide(result, op1, op2, spare);
	    else
		acc->val.ul = (unsigned long)((signed long)acc->val.ul /
					      (signed long)operand->val.ul);
	    break;
	case YASM_EXPR_MOD:
	    if (result) {
		/* TODO: make sure op1 and op2 are unsigned */
		BitVector_Divide(spare, op1, op2, result);
	    } else
		acc->val.ul = acc->val.ul % operand->val.ul;
	    break;
	case YASM_EXPR_SIGNMOD:
	    if (result)
		BitVector_Divide(spare, op1, op2, result);
	    else
		acc->val.ul = (unsigned long)((signed long)acc->val.ul %
					      (signed long)operand->val.ul);
	    break;
	case YASM_EXPR_NEG:
	    if (result)
		BitVector_Negate(result, op1);
	    else
		acc->val.ul = -(acc->val.ul);
	    break;
	case YASM_EXPR_NOT:
	    if (result)
		Set_Complement(result, op1);
	    else
		acc->val.ul = ~(acc->val.ul);
	    break;
	case YASM_EXPR_OR:
	    if (result)
		Set_Union(result, op1, op2);
	    else
		acc->val.ul = acc->val.ul | operand->val.ul;
	    break;
	case YASM_EXPR_AND:
	    if (result)
		Set_Intersection(result, op1, op2);
	    else
		acc->val.ul = acc->val.ul & operand->val.ul;
	    break;
	case YASM_EXPR_XOR:
	    if (result)
		Set_ExclusiveOr(result, op1, op2);
	    else
		acc->val.ul = acc->val.ul ^ operand->val.ul;
	    break;
	case YASM_EXPR_SHL:
	    if (result) {
		if (operand->type == INTNUM_UL) {
		    BitVector_Copy(result, op1);
		    BitVector_Move_Left(result, (N_int)operand->val.ul);
		} else	/* don't even bother, just zero result */
		    BitVector_Empty(result);
	    } else
		acc->val.ul = acc->val.ul << operand->val.ul;
	    break;
	case YASM_EXPR_SHR:
	    if (result) {
		if (operand->type == INTNUM_UL) {
		    BitVector_Copy(result, op1);
		    BitVector_Move_Right(result, (N_int)operand->val.ul);
		} else	/* don't even bother, just zero result */
		    BitVector_Empty(result);
	    } else
		acc->val.ul = acc->val.ul >> operand->val.ul;
	    break;
	case YASM_EXPR_LOR:
	    if (result) {
		BitVector_Empty(result);
		BitVector_LSB(result, !BitVector_is_empty(op1) ||
			      !BitVector_is_empty(op2));
	    } else
		acc->val.ul = acc->val.ul || operand->val.ul;
	    break;
	case YASM_EXPR_LAND:
	    if (result) {
		BitVector_Empty(result);
		BitVector_LSB(result, !BitVector_is_empty(op1) &&
			      !BitVector_is_empty(op2));
	    } else
		acc->val.ul = acc->val.ul && operand->val.ul;
	    break;
	case YASM_EXPR_LNOT:
	    if (result) {
		BitVector_Empty(result);
		BitVector_LSB(result, BitVector_is_empty(op1));
	    } else
		acc->val.ul = !acc->val.ul;
	    break;
	case YASM_EXPR_EQ:
	    if (result) {
		BitVector_Empty(result);
		BitVector_LSB(result, BitVector_equal(op1, op2));
	    } else
		acc->val.ul = acc->val.ul == operand->val.ul;
	    break;
	case YASM_EXPR_LT:
	    if (result) {
		BitVector_Empty(result);
		BitVector_LSB(result, BitVector_Lexicompare(op1, op2) < 0);
	    } else
		acc->val.ul = acc->val.ul < operand->val.ul;
	    break;
	case YASM_EXPR_GT:
	    if (result) {
		BitVector_Empty(result);
		BitVector_LSB(result, BitVector_Lexicompare(op1, op2) > 0);
	    } else
		acc->val.ul = acc->val.ul > operand->val.ul;
	    break;
	case YASM_EXPR_LE:
	    if (result) {
		BitVector_Empty(result);
		BitVector_LSB(result, BitVector_Lexicompare(op1, op2) <= 0);
	    } else
		acc->val.ul = acc->val.ul <= operand->val.ul;
	    break;
	case YASM_EXPR_GE:
	    if (result) {
		BitVector_Empty(result);
		BitVector_LSB(result, BitVector_Lexicompare(op1, op2) >= 0);
	    } else
		acc->val.ul = acc->val.ul >= operand->val.ul;
	    break;
	case YASM_EXPR_NE:
	    if (result) {
		BitVector_Empty(result);
		BitVector_LSB(result, !BitVector_equal(op1, op2));
	    } else
		acc->val.ul = acc->val.ul != operand->val.ul;
	    break;
	case YASM_EXPR_SEG:
	    yasm__error(lindex, N_("invalid use of '%s'"), "SEG");
	    break;
	case YASM_EXPR_WRT:
	    yasm__error(lindex, N_("invalid use of '%s'"), "WRT");
	    break;
	case YASM_EXPR_SEGOFF:
	    yasm__error(lindex, N_("invalid use of '%s'"), ":");
	    break;
	case YASM_EXPR_IDENT:
	    if (result)
		BitVector_Copy(result, op1);
	    break;
	default:
	    yasm_internal_error(N_("invalid operation in intnum calculation"));
    }

    /* If we were doing a bitvector computation... */
    if (result) {
	BitVector_Destroy(spare);

	if (op1 && acc->type != INTNUM_BV)
	    BitVector_Destroy(op1);
	if (op2 && operand && operand->type != INTNUM_BV)
	    BitVector_Destroy(op2);

	/* Try to fit the result into 32 bits if possible */
	if (Set_Max(result) < 32) {
	    if (acc->type == INTNUM_BV) {
		BitVector_Destroy(acc->val.bv);
		acc->type = INTNUM_UL;
	    }
	    acc->val.ul = BitVector_Chunk_Read(result, 32, 0);
	    BitVector_Destroy(result);
	} else {
	    if (acc->type == INTNUM_BV) {
		BitVector_Copy(acc->val.bv, result);
		BitVector_Destroy(result);
	    } else {
		acc->type = INTNUM_BV;
		acc->val.bv = result;
	    }
	}
    }
}
/*@=nullderef =nullpass =branchstate@*/

int
yasm_intnum_is_zero(yasm_intnum *intn)
{
    return ((intn->type == INTNUM_UL && intn->val.ul == 0) ||
	    (intn->type == INTNUM_BV && BitVector_is_empty(intn->val.bv)));
}

int
yasm_intnum_is_pos1(yasm_intnum *intn)
{
    return ((intn->type == INTNUM_UL && intn->val.ul == 1) ||
	    (intn->type == INTNUM_BV && Set_Max(intn->val.bv) == 0));
}

int
yasm_intnum_is_neg1(yasm_intnum *intn)
{
    return ((intn->type == INTNUM_UL && (long)intn->val.ul == -1) ||
	    (intn->type == INTNUM_BV && BitVector_is_full(intn->val.bv)));
}

unsigned long
yasm_intnum_get_uint(const yasm_intnum *intn)
{
    switch (intn->type) {
	case INTNUM_UL:
	    return intn->val.ul;
	case INTNUM_BV:
	    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_UL:
	    return (long)intn->val.ul;
	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.
		 */
		intptr abs_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
		long retval;

		BitVector_Negate(abs_bv, intn->val.bv);
		retval = -((long)BitVector_Chunk_Read(abs_bv, 32, 0));

		BitVector_Destroy(abs_bv);
		return retval;
	    } else
		return (long)BitVector_Chunk_Read(intn->val.bv, 32, 0);
	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 size)
{
    unsigned long ul;
    unsigned char *buf;
    unsigned int len;

    switch (intn->type) {
	case INTNUM_UL:
	    ul = intn->val.ul;
	    while (size-- > 0) {
		YASM_WRITE_8(ptr, ul);
		if (ul != 0)
		    ul >>= 8;
	    }
	    break;
	case INTNUM_BV:
	    buf = BitVector_Block_Read(intn->val.bv, &len);
	    if (len < (unsigned int)size)
		yasm_internal_error(N_("Invalid size specified (too large)"));
	    memcpy(ptr, buf, size);
	    yasm_xfree(buf);
	    break;
    }
}

/* Return 1 if okay size, 0 if not */
int
yasm_intnum_check_size(const yasm_intnum *intn, size_t size, int is_signed)
{
    if (is_signed) {
	long absl;

	switch (intn->type) {
	    case INTNUM_UL:
		if (size >= 4)
		    return 1;
		/* absl = absolute value of (long)intn->val.ul */
		absl = (long)intn->val.ul;
		if (absl < 0)
		    absl = -absl;

		switch (size) {
		    case 3:
			return ((absl & 0x00FFFFFF) == absl);
		    case 2:
			return ((absl & 0x0000FFFF) == absl);
		    case 1:
			return ((absl & 0x000000FF) == absl);
		}
		break;
	    case INTNUM_BV:
		if (size >= 10)
		    return 1;
		if (BitVector_msb_(intn->val.bv)) {
		    /* it's negative */
		    intptr abs_bv = BitVector_Create(BITVECT_ALLOC_SIZE,
						     FALSE);
		    int retval;

		    BitVector_Negate(abs_bv, intn->val.bv);
		    retval = Set_Max(abs_bv) < (long)(size*8);

		    BitVector_Destroy(abs_bv);
		    return retval;
		} else
		    return (Set_Max(intn->val.bv) < (long)(size*8));
	}
    } else {
	switch (intn->type) {
	    case INTNUM_UL:
		if (size >= 4)
		    return 1;
		switch (size) {
		    case 3:
			return ((intn->val.ul & 0x00FFFFFF) == intn->val.ul);
		    case 2:
			return ((intn->val.ul & 0x0000FFFF) == intn->val.ul);
		    case 1:
			return ((intn->val.ul & 0x000000FF) == intn->val.ul);
		}
		break;
	    case INTNUM_BV:
		if (size >= 10)
		    return 1;
		else
		    return (Set_Max(intn->val.bv) < (long)(size*8));
	}
    }
    return 0;
}

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

    switch (intn->type) {
	case INTNUM_UL:
	    fprintf(f, "0x%lx/%u", intn->val.ul, (unsigned int)intn->origsize);
	    break;
	case INTNUM_BV:
	    s = BitVector_to_Hex(intn->val.bv);
	    fprintf(f, "0x%s/%u", (char *)s, (unsigned int)intn->origsize);
	    yasm_xfree(s);
	    break;
    }
}
