コード例 #1
0
ファイル: intnum.c プロジェクト: kstephens/yasm
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);
}
コード例 #2
0
ファイル: x86arch.c プロジェクト: Acidburn0zzz/yasm
static /*@only@*/ yasm_arch *
x86_create(const char *machine, const char *parser,
           /*@out@*/ yasm_arch_create_error *error)
{
    yasm_arch_x86 *arch_x86;
    unsigned int amd64_machine, address_size;

    *error = YASM_ARCH_CREATE_OK;

    if (yasm__strcasecmp(machine, "x86") == 0) {
        amd64_machine = 0;
	address_size = 32;
    } else if (yasm__strcasecmp(machine, "amd64") == 0) {
        amd64_machine = 1;
	address_size = 64;
    } else if (yasm__strcasecmp(machine, "x32") == 0) {
        amd64_machine = 1;
	address_size = 32;
    }
    else {
        *error = YASM_ARCH_CREATE_BAD_MACHINE;
        return NULL;
    }

    arch_x86 = yasm_xmalloc(sizeof(yasm_arch_x86));

    arch_x86->arch.module = &yasm_x86_LTX_arch;

    /* default to all instructions/features enabled */
    arch_x86->active_cpu = 0;
    arch_x86->cpu_enables_size = 1;
    arch_x86->cpu_enables = yasm_xmalloc(sizeof(wordptr));
    arch_x86->cpu_enables[0] = BitVector_Create(64, FALSE);
    BitVector_Fill(arch_x86->cpu_enables[0]);

    arch_x86->amd64_machine = amd64_machine;
    arch_x86->mode_bits = 0;
    arch_x86->address_size = address_size;
    arch_x86->force_strict = 0;
    arch_x86->default_rel = 0;
    arch_x86->gas_intel_mode = 0;
    arch_x86->nop = X86_NOP_BASIC;

    if (yasm__strcasecmp(parser, "nasm") == 0)
        arch_x86->parser = X86_PARSER_NASM;
    else if (yasm__strcasecmp(parser, "tasm") == 0)
        arch_x86->parser = X86_PARSER_TASM;
    else if (yasm__strcasecmp(parser, "gas") == 0
             || yasm__strcasecmp(parser, "gnu") == 0)
        arch_x86->parser = X86_PARSER_GAS;
    else {
        yasm_xfree(arch_x86);
        *error = YASM_ARCH_CREATE_BAD_PARSER;
        return NULL;
    }

    return (yasm_arch *)arch_x86;
}
コード例 #3
0
ファイル: intnum.c プロジェクト: kstephens/yasm
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;
    }
}
コード例 #4
0
ファイル: intnum.c プロジェクト: kstephens/yasm
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;
}
コード例 #5
0
ファイル: floatnum.c プロジェクト: Acidburn0zzz/yasm
static void
POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp)
{
    /* Save decimal exponent */
    e->dec_exponent = dec_exp;

    /* Initialize mantissa */
    e->f.mantissa = BitVector_Create(MANT_BITS, FALSE);
    BitVector_Block_Store(e->f.mantissa, s->mantissa, MANT_BYTES);

    /* Initialize exponent */
    e->f.exponent = s->exponent;

    /* Set sign to 0 (positive) */
    e->f.sign = 0;

    /* Clear flags */
    e->f.flags = 0;
}
コード例 #6
0
static void
num_family_setup(void)
{
    BitVector_Boot();
    testval = BitVector_Create(80, FALSE);
}
コード例 #7
0
ファイル: floatnum.c プロジェクト: Acidburn0zzz/yasm
/* Function used by conversion routines to actually perform the conversion.
 *
 * ptr -> the array to return the little-endian floating point value into.
 * flt -> the floating point value to convert.
 * byte_size -> the size in bytes of the output format.
 * mant_bits -> the size in bits of the output mantissa.
 * implicit1 -> does the output format have an implicit 1? 1=yes, 0=no.
 * exp_bits -> the size in bits of the output exponent.
 *
 * Returns 0 on success, 1 if overflow, -1 if underflow.
 */
static int
floatnum_get_common(const yasm_floatnum *flt, /*@out@*/ unsigned char *ptr,
                    N_int byte_size, N_int mant_bits, int implicit1,
                    N_int exp_bits)
{
    long exponent = (long)flt->exponent;
    wordptr output;
    charptr buf;
    unsigned int len;
    unsigned int overflow = 0, underflow = 0;
    int retval = 0;
    long exp_bias = (1<<(exp_bits-1))-1;
    long exp_inf = (1<<exp_bits)-1;

    output = BitVector_Create(byte_size*8, TRUE);

    /* copy mantissa */
    BitVector_Interval_Copy(output, flt->mantissa, 0,
                            (N_int)((MANT_BITS-implicit1)-mant_bits),
                            mant_bits);

    /* round mantissa */
    if (BitVector_bit_test(flt->mantissa, (MANT_BITS-implicit1)-(mant_bits+1)))
        BitVector_increment(output);

    if (BitVector_bit_test(output, mant_bits)) {
        /* overflowed, so zero mantissa (and set explicit bit if necessary) */
        BitVector_Empty(output);
        BitVector_Bit_Copy(output, mant_bits-1, !implicit1);
        /* and up the exponent (checking for overflow) */
        if (exponent+1 >= EXP_INF)
            overflow = 1;
        else
            exponent++;
    }

    /* adjust the exponent to the output bias, checking for overflow */
    exponent -= EXP_BIAS-exp_bias;
    if (exponent >= exp_inf)
        overflow = 1;
    else if (exponent <= 0)
        underflow = 1;

    /* underflow and overflow both set!? */
    if (underflow && overflow)
        yasm_internal_error(N_("Both underflow and overflow set"));

    /* check for underflow or overflow and set up appropriate output */
    if (underflow) {
        BitVector_Empty(output);
        exponent = 0;
        if (!(flt->flags & FLAG_ISZERO))
            retval = -1;
    } else if (overflow) {
        BitVector_Empty(output);
        exponent = exp_inf;
        retval = 1;
    }

    /* move exponent into place */
    BitVector_Chunk_Store(output, exp_bits, mant_bits, (N_long)exponent);

    /* merge in sign bit */
    BitVector_Bit_Copy(output, byte_size*8-1, flt->sign);

    /* get little-endian bytes */
    buf = BitVector_Block_Read(output, &len);
    if (len < byte_size)
        yasm_internal_error(
            N_("Byte length of BitVector does not match bit length"));

    /* copy to output */
    memcpy(ptr, buf, byte_size*sizeof(unsigned char));

    /* free allocated resources */
    yasm_xfree(buf);

    BitVector_Destroy(output);

    return retval;
}
コード例 #8
0
ファイル: floatnum.c プロジェクト: Acidburn0zzz/yasm
yasm_floatnum *
yasm_floatnum_create(const char *str)
{
    yasm_floatnum *flt;
    int dec_exponent, dec_exp_add;      /* decimal (powers of 10) exponent */
    int POT_index;
    wordptr operand[2];
    int sig_digits;
    int decimal_pt;
    boolean carry;

    flt = yasm_xmalloc(sizeof(yasm_floatnum));

    flt->mantissa = BitVector_Create(MANT_BITS, TRUE);

    /* allocate and initialize calculation variables */
    operand[0] = BitVector_Create(MANT_BITS, TRUE);
    operand[1] = BitVector_Create(MANT_BITS, TRUE);
    dec_exponent = 0;
    sig_digits = 0;
    decimal_pt = 1;

    /* set initial flags to 0 */
    flt->flags = 0;

    /* check for + or - character and skip */
    if (*str == '-') {
        flt->sign = 1;
        str++;
    } else if (*str == '+') {
        flt->sign = 0;
        str++;
    } else
        flt->sign = 0;

    /* eliminate any leading zeros (which do not count as significant digits) */
    while (*str == '0')
        str++;

    /* When we reach the end of the leading zeros, first check for a decimal
     * point.  If the number is of the form "0---0.0000" we need to get rid
     * of the zeros after the decimal point and not count them as significant
     * digits.
     */
    if (*str == '.') {
        str++;
        while (*str == '0') {
            str++;
            dec_exponent--;
        }
    } else {
        /* The number is of the form "yyy.xxxx" (where y <> 0). */
        while (isdigit(*str)) {
            /* See if we've processed more than the max significant digits: */
            if (sig_digits < MANT_SIGDIGITS) {
                /* Multiply mantissa by 10 [x = (x<<1)+(x<<3)] */
                BitVector_shift_left(flt->mantissa, 0);
                BitVector_Copy(operand[0], flt->mantissa);
                BitVector_Move_Left(flt->mantissa, 2);
                carry = 0;
                BitVector_add(operand[1], operand[0], flt->mantissa, &carry);

                /* Add in current digit */
                BitVector_Empty(operand[0]);
                BitVector_Chunk_Store(operand[0], 4, 0, (N_long)(*str-'0'));
                carry = 0;
                BitVector_add(flt->mantissa, operand[1], operand[0], &carry);
            } else {
                /* Can't integrate more digits with mantissa, so instead just
                 * raise by a power of ten.
                 */
                dec_exponent++;
            }
            sig_digits++;
            str++;
        }

        if (*str == '.')
            str++;
        else
            decimal_pt = 0;
    }

    if (decimal_pt) {
        /* Process the digits to the right of the decimal point. */
        while (isdigit(*str)) {
            /* See if we've processed more than 19 significant digits: */
            if (sig_digits < 19) {
                /* Raise by a power of ten */
                dec_exponent--;

                /* Multiply mantissa by 10 [x = (x<<1)+(x<<3)] */
                BitVector_shift_left(flt->mantissa, 0);
                BitVector_Copy(operand[0], flt->mantissa);
                BitVector_Move_Left(flt->mantissa, 2);
                carry = 0;
                BitVector_add(operand[1], operand[0], flt->mantissa, &carry);

                /* Add in current digit */
                BitVector_Empty(operand[0]);
                BitVector_Chunk_Store(operand[0], 4, 0, (N_long)(*str-'0'));
                carry = 0;
                BitVector_add(flt->mantissa, operand[1], operand[0], &carry);
            }
            sig_digits++;
            str++;
        }
    }

    if (*str == 'e' || *str == 'E') {
        str++;
        /* We just saw the "E" character, now read in the exponent value and
         * add it into dec_exponent.
         */
        dec_exp_add = 0;
        sscanf(str, "%d", &dec_exp_add);
        dec_exponent += dec_exp_add;
    }

    /* Free calculation variables. */
    BitVector_Destroy(operand[1]);
    BitVector_Destroy(operand[0]);

    /* Normalize the number, checking for 0 first. */
    if (BitVector_is_empty(flt->mantissa)) {
        /* Mantissa is 0, zero exponent too. */
        flt->exponent = 0;
        /* Set zero flag so output functions don't see 0 value as underflow. */
        flt->flags |= FLAG_ISZERO;
        /* Return 0 value. */
        return flt;
    }
    /* Exponent if already norm. */
    flt->exponent = (unsigned short)(0x7FFF+(MANT_BITS-1));
    floatnum_normalize(flt);

    /* The number is normalized.  Now multiply by 10 the number of times
     * specified in DecExponent.  This uses the power of ten tables to speed
     * up this operation (and make it more accurate).
     */
    if (dec_exponent > 0) {
        POT_index = 0;
        /* Until we hit 1.0 or finish exponent or overflow */
        while ((POT_index < 14) && (dec_exponent != 0) &&
               (flt->exponent != EXP_INF)) {
            /* Find the first power of ten in the table which is just less than
             * the exponent.
             */
            while (dec_exponent < POT_TableP[POT_index].dec_exponent)
                POT_index++;

            if (POT_index < 14) {
                /* Subtract out what we're multiplying in from exponent */
                dec_exponent -= POT_TableP[POT_index].dec_exponent;

                /* Multiply by current power of 10 */
                floatnum_mul(flt, &POT_TableP[POT_index].f);
            }
        }
    } else if (dec_exponent < 0) {
        POT_index = 0;
        /* Until we hit 1.0 or finish exponent or underflow */
        while ((POT_index < 14) && (dec_exponent != 0) &&
               (flt->exponent != EXP_ZERO)) {
            /* Find the first power of ten in the table which is just less than
             * the exponent.
             */
            while (dec_exponent > POT_TableN[POT_index].dec_exponent)
                POT_index++;

            if (POT_index < 14) {
                /* Subtract out what we're multiplying in from exponent */
                dec_exponent -= POT_TableN[POT_index].dec_exponent;

                /* Multiply by current power of 10 */
                floatnum_mul(flt, &POT_TableN[POT_index].f);
            }
        }
    }

    /* Round the result. (Don't round underflow or overflow).  Also don't
     * increment if this would cause the mantissa to wrap.
     */
    if ((flt->exponent != EXP_INF) && (flt->exponent != EXP_ZERO) &&
        !BitVector_is_full(flt->mantissa))
        BitVector_increment(flt->mantissa);

    return flt;
}
コード例 #9
0
ファイル: floatnum.c プロジェクト: Acidburn0zzz/yasm
/* 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);
}
コード例 #10
0
ファイル: floatnum_test.c プロジェクト: kstephens/yasm
static void
get_family_setup(void)
{
    flt = malloc(sizeof(yasm_floatnum));
    flt->mantissa = BitVector_Create(MANT_BITS, TRUE);
}