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); }
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_destroy(yasm_intnum *intn) { if (intn->type == INTNUM_BV) BitVector_Destroy(intn->val.bv); yasm_xfree(intn); }
/*@-globstate@*/ void yasm_floatnum_cleanup(void) { int i; /* Un-offset POT_TableP */ POT_TableP--; for (i=0; i<14; i++) { BitVector_Destroy(POT_TableN[i].f.mantissa); BitVector_Destroy(POT_TableP[i].f.mantissa); } BitVector_Destroy(POT_TableP[14].f.mantissa); yasm_xfree(POT_TableN); yasm_xfree(POT_TableP); }
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; }
static void x86_destroy(/*@only@*/ yasm_arch *arch) { yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch; unsigned int i; for (i=0; i<arch_x86->cpu_enables_size; i++) BitVector_Destroy(arch_x86->cpu_enables[i]); yasm_xfree(arch_x86->cpu_enables); yasm_xfree(arch); }
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; } }
static void num_family_teardown(void) { BitVector_Destroy(testval); }
/* 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; }
void yasm_floatnum_destroy(yasm_floatnum *flt) { BitVector_Destroy(flt->mantissa); yasm_xfree(flt); }
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; }
/* 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); }
static void get_family_teardown(void) { BitVector_Destroy(flt->mantissa); free(flt); }
/*@-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; }