+/*
+ * convert a floating point value into an sc value ...
+ */
+int fc_flt2int(const fp_value *a, void *result, ir_mode *dst_mode)
+{
+ if (a->desc.clss == NORMAL) {
+ int exp_bias = (1 << (a->desc.exponent_size - 1)) - 1;
+ int exp_val = sc_val_to_long(_exp(a)) - exp_bias;
+ int shift, highest;
+ int mantissa_size;
+ int tgt_bits;
+
+ if (a->sign && !mode_is_signed(dst_mode)) {
+ /* FIXME: for now we cannot convert this */
+ return 0;
+ }
+
+ tgt_bits = get_mode_size_bits(dst_mode);
+ if (mode_is_signed(dst_mode))
+ --tgt_bits;
+
+ assert(exp_val >= 0 && "floating point value not integral before fc_flt2int() call");
+ mantissa_size = a->desc.mantissa_size + ROUNDING_BITS;
+ shift = exp_val - mantissa_size;
+
+ if (tgt_bits < mantissa_size + 1)
+ tgt_bits = mantissa_size + 1;
+ if (shift > 0) {
+ sc_shlI(_mant(a), shift, tgt_bits, 0, result);
+ } else {
+ sc_shrI(_mant(a), -shift, tgt_bits, 0, result);
+ }
+
+ /* check for overflow */
+ highest = sc_get_highest_set_bit(result);
+
+ if (mode_is_signed(dst_mode)) {
+ if (highest == sc_get_lowest_set_bit(result)) {
+ /* need extra test for MIN_INT */
+ if (highest >= (int) get_mode_size_bits(dst_mode)) {
+ /* FIXME: handle overflow */
+ return 0;
+ }
+ } else {
+ if (highest >= (int) get_mode_size_bits(dst_mode) - 1) {
+ /* FIXME: handle overflow */
+ return 0;
+ }
+ }
+ } else {
+ if (highest >= (int) get_mode_size_bits(dst_mode)) {
+ /* FIXME: handle overflow */
+ return 0;
+ }
+ }
+
+ if (a->sign)
+ sc_neg(result, result);
+
+ return 1;
+ }
+ else if (a->desc.clss == ZERO) {
+ sc_zero(result);
+ return 1;
+ }
+ return 0;
+}
+
+
+unsigned fc_set_immediate_precision(unsigned bits)
+{
+ unsigned old = immediate_prec;
+
+ immediate_prec = bits;
+ return old;
+}
+
+int fc_is_exact(void)
+{
+ return fc_exact;