Reapply reverted change:
gcc/ada/ Reapply reverted change: 2007-09-06 Eric Botcazou <ebotcazou@adacore.com> * trans.c (convert_with_check): Update call to real_2expN. gcc/ config/m68k/m68k.c (floating_exact_log2): Update call to real_2expN. config/s390/s390.md (fixuns_trunc<BFP:mode><GPR:mode>2): Ditto. Reapply reverted changes: 2007-09-06 Jan Hubicka <jh@suse.cz> * config/i386.c (ix86_expand_lround, ix86_expand_round): Update call of real_2expN. 2007-09-06 Richard Sandiford <richard@codesourcery.com> * config/mips/mips.md (fixuns_truncdfsi2, fixuns_truncdfdi2) (fixuns_truncsfsi2, fixuns_truncsfdi2): Update calls to real_2expN. 2007-09-05 Janis Johnson <janis187@us.ibm.com> * optabs.c (expand_float): Convert unsigned integer as signed only if it provides sufficient accuracy; add mode argument to real_2expN. (expand_fix): Fix comment typos; extend binary float into mode wider than destination for converion to unsigned integer; add mode argument to real_2expN. * real.c (real_2expN): Add mode argument to special-case decimal float values. * real.h (real_2expN): Ditto. * fixed-value.c (check_real_for_fixed_mode): Add mode argument to real_2expN. (fixed_from_string): Ditto. (fixed_to_decimal): Ditto. (fixed_convert_from_real): Ditto. (real_convert_from_fixed): Ditto. * config/rs6000/rs6000.md (FP): Include DD and TD modes. * config/rs6000/dfp.md (extendddtd2, adddd3, addtd3, subdd3, subtd3, muldd3, multd3, divdd3, divtd3, cmpdd_internal1, cmptd_internal1, floatditd2, ftruncdd2, fixdddi2, ftrunctd2, fixddi2): New. From-SVN: r128247
This commit is contained in:
parent
b48d035854
commit
6ef9a246ce
13 changed files with 231 additions and 29 deletions
|
@ -1,3 +1,41 @@
|
|||
2007-09-07 Janis Johnson <janis187@us.ibm.com>
|
||||
|
||||
config/m68k/m68k.c (floating_exact_log2): Update call to real_2expN.
|
||||
config/s390/s390.md (fixuns_trunc<BFP:mode><GPR:mode>2): Ditto.
|
||||
|
||||
Reapply reverted changes:
|
||||
|
||||
2007-09-06 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* config/i386.c (ix86_expand_lround, ix86_expand_round): Update call of
|
||||
real_2expN.
|
||||
|
||||
2007-09-06 Richard Sandiford <richard@codesourcery.com>
|
||||
|
||||
* config/mips/mips.md (fixuns_truncdfsi2, fixuns_truncdfdi2)
|
||||
(fixuns_truncsfsi2, fixuns_truncsfdi2): Update calls to real_2expN.
|
||||
|
||||
2007-09-05 Janis Johnson <janis187@us.ibm.com>
|
||||
|
||||
* optabs.c (expand_float): Convert unsigned integer as signed only
|
||||
if it provides sufficient accuracy; add mode argument to real_2expN.
|
||||
(expand_fix): Fix comment typos; extend binary float into mode
|
||||
wider than destination for converion to unsigned integer; add mode
|
||||
argument to real_2expN.
|
||||
* real.c (real_2expN): Add mode argument to special-case decimal
|
||||
float values.
|
||||
* real.h (real_2expN): Ditto.
|
||||
* fixed-value.c (check_real_for_fixed_mode): Add mode argument to
|
||||
real_2expN.
|
||||
(fixed_from_string): Ditto.
|
||||
(fixed_to_decimal): Ditto.
|
||||
(fixed_convert_from_real): Ditto.
|
||||
(real_convert_from_fixed): Ditto.
|
||||
* config/rs6000/rs6000.md (FP): Include DD and TD modes.
|
||||
* config/rs6000/dfp.md (extendddtd2, adddd3, addtd3, subdd3, subtd3,
|
||||
muldd3, multd3, divdd3, divtd3, cmpdd_internal1, cmptd_internal1,
|
||||
floatditd2, ftruncdd2, fixdddi2, ftrunctd2, fixddi2): New.
|
||||
|
||||
2007-09-07 Diego Novillo <dnovillo@google.com>
|
||||
|
||||
* tree-flow.h (const_block_stmt_iterator): Remove.
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2007-09-07 Janis Johnson <janis187@us.ibm.com>
|
||||
|
||||
Reapply reverted change:
|
||||
|
||||
2007-09-06 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* trans.c (convert_with_check): Update call to real_2expN.
|
||||
|
||||
2007-09-06 Janis Johnson <janis187@us.ibm.com>
|
||||
|
||||
Revert:
|
||||
|
|
|
@ -5893,7 +5893,7 @@ convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflowp,
|
|||
|
||||
/* Compute the exact value calc_type'Pred (0.5) at compile time. */
|
||||
fmt = REAL_MODE_FORMAT (TYPE_MODE (calc_type));
|
||||
real_2expN (&half_minus_pred_half, -(fmt->p) - 1);
|
||||
real_2expN (&half_minus_pred_half, -(fmt->p) - 1, TYPE_MODE (calc_type));
|
||||
REAL_ARITHMETIC (pred_half, MINUS_EXPR, dconsthalf,
|
||||
half_minus_pred_half);
|
||||
gnu_pred_half = build_real (calc_type, pred_half);
|
||||
|
|
|
@ -23144,7 +23144,7 @@ ix86_expand_lround (rtx op0, rtx op1)
|
|||
|
||||
/* load nextafter (0.5, 0.0) */
|
||||
fmt = REAL_MODE_FORMAT (mode);
|
||||
real_2expN (&half_minus_pred_half, -(fmt->p) - 1);
|
||||
real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
|
||||
REAL_ARITHMETIC (pred_half, MINUS_EXPR, dconsthalf, half_minus_pred_half);
|
||||
|
||||
/* adj = copysign (0.5, op1) */
|
||||
|
@ -23555,7 +23555,7 @@ ix86_expand_round (rtx operand0, rtx operand1)
|
|||
|
||||
/* load nextafter (0.5, 0.0) */
|
||||
fmt = REAL_MODE_FORMAT (mode);
|
||||
real_2expN (&half_minus_pred_half, -(fmt->p) - 1);
|
||||
real_2expN (&half_minus_pred_half, -(fmt->p) - 1, mode);
|
||||
REAL_ARITHMETIC (pred_half, MINUS_EXPR, dconsthalf, half_minus_pred_half);
|
||||
|
||||
/* xa = xa + 0.5 */
|
||||
|
|
|
@ -3571,7 +3571,7 @@ floating_exact_log2 (rtx x)
|
|||
return 0;
|
||||
|
||||
exp = real_exponent (&r);
|
||||
real_2expN (&r1, exp);
|
||||
real_2expN (&r1, exp, DFmode);
|
||||
if (REAL_VALUES_EQUAL (r1, r))
|
||||
return exp;
|
||||
|
||||
|
|
|
@ -2805,7 +2805,7 @@
|
|||
rtx label2 = gen_label_rtx ();
|
||||
REAL_VALUE_TYPE offset;
|
||||
|
||||
real_2expN (&offset, 31);
|
||||
real_2expN (&offset, 31, DFmode);
|
||||
|
||||
if (reg1) /* Turn off complaints about unreached code. */
|
||||
{
|
||||
|
@ -2850,7 +2850,7 @@
|
|||
rtx label2 = gen_label_rtx ();
|
||||
REAL_VALUE_TYPE offset;
|
||||
|
||||
real_2expN (&offset, 63);
|
||||
real_2expN (&offset, 63, DFmode);
|
||||
|
||||
mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
|
||||
do_pending_stack_adjust ();
|
||||
|
@ -2892,7 +2892,7 @@
|
|||
rtx label2 = gen_label_rtx ();
|
||||
REAL_VALUE_TYPE offset;
|
||||
|
||||
real_2expN (&offset, 31);
|
||||
real_2expN (&offset, 31, SFmode);
|
||||
|
||||
mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
|
||||
do_pending_stack_adjust ();
|
||||
|
@ -2934,7 +2934,7 @@
|
|||
rtx label2 = gen_label_rtx ();
|
||||
REAL_VALUE_TYPE offset;
|
||||
|
||||
real_2expN (&offset, 63);
|
||||
real_2expN (&offset, 63, SFmode);
|
||||
|
||||
mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
|
||||
do_pending_stack_adjust ();
|
||||
|
|
|
@ -405,3 +405,151 @@
|
|||
{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
|
||||
[(set_attr "length" "8,8,8,20,20,16")])
|
||||
|
||||
;; Hardware support for decimal floating point operations.
|
||||
|
||||
(define_insn "extendddtd2"
|
||||
[(set (match_operand:TD 0 "gpc_reg_operand" "=f")
|
||||
(float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"dctqpq %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
;; The result of drdpq is an even/odd register pair with the converted
|
||||
;; value in the even register and zero in the odd register.
|
||||
;; FIXME: Avoid the register move by using a reload constraint to ensure
|
||||
;; that the result is the first of the pair receiving the result of drdpq.
|
||||
|
||||
(define_insn "trunctddd2"
|
||||
[(set (match_operand:DD 0 "gpc_reg_operand" "=f")
|
||||
(float_truncate:DD (match_operand:TD 1 "gpc_reg_operand" "f")))
|
||||
(clobber (match_scratch:TD 2 "=f"))]
|
||||
"TARGET_DFP"
|
||||
"drdpq %2,%1\;fmr %0,%2"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "adddd3"
|
||||
[(set (match_operand:DD 0 "gpc_reg_operand" "=f")
|
||||
(plus:DD (match_operand:DD 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:DD 2 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"dadd %0,%1,%2"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "addtd3"
|
||||
[(set (match_operand:TD 0 "gpc_reg_operand" "=f")
|
||||
(plus:TD (match_operand:TD 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:TD 2 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"daddq %0,%1,%2"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "subdd3"
|
||||
[(set (match_operand:DD 0 "gpc_reg_operand" "=f")
|
||||
(minus:DD (match_operand:DD 1 "gpc_reg_operand" "f")
|
||||
(match_operand:DD 2 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"dsub %0,%1,%2"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "subtd3"
|
||||
[(set (match_operand:TD 0 "gpc_reg_operand" "=f")
|
||||
(minus:TD (match_operand:TD 1 "gpc_reg_operand" "f")
|
||||
(match_operand:TD 2 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"dsubq %0,%1,%2"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "muldd3"
|
||||
[(set (match_operand:DD 0 "gpc_reg_operand" "=f")
|
||||
(mult:DD (match_operand:DD 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:DD 2 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"dmul %0,%1,%2"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "multd3"
|
||||
[(set (match_operand:TD 0 "gpc_reg_operand" "=f")
|
||||
(mult:TD (match_operand:TD 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:TD 2 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"dmulq %0,%1,%2"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "divdd3"
|
||||
[(set (match_operand:DD 0 "gpc_reg_operand" "=f")
|
||||
(div:DD (match_operand:DD 1 "gpc_reg_operand" "f")
|
||||
(match_operand:DD 2 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"ddiv %0,%1,%2"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "divtd3"
|
||||
[(set (match_operand:TD 0 "gpc_reg_operand" "=f")
|
||||
(div:TD (match_operand:TD 1 "gpc_reg_operand" "f")
|
||||
(match_operand:TD 2 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"ddivq %0,%1,%2"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "*cmpdd_internal1"
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
(compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "f")
|
||||
(match_operand:DD 2 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"dcmpu %0,%1,%2"
|
||||
[(set_attr "type" "fpcompare")])
|
||||
|
||||
(define_insn "*cmptd_internal1"
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
(compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "f")
|
||||
(match_operand:TD 2 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"dcmpuq %0,%1,%2"
|
||||
[(set_attr "type" "fpcompare")])
|
||||
|
||||
(define_insn "floatditd2"
|
||||
[(set (match_operand:TD 0 "gpc_reg_operand" "=f")
|
||||
(float:TD (match_operand:DI 1 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"dcffixq %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
;; Convert a decimal64 to a decimal64 whose value is an integer.
|
||||
;; This is the first stage of converting it to an integer type.
|
||||
|
||||
(define_insn "ftruncdd2"
|
||||
[(set (match_operand:DD 0 "gpc_reg_operand" "=f")
|
||||
(fix:DD (match_operand:DD 1 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"drintn. 0,%0,%1,1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
;; Convert a decimal64 whose value is an integer to an actual integer.
|
||||
;; This is the second stage of converting decimal float to integer type.
|
||||
|
||||
(define_insn "fixdddi2"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=f")
|
||||
(fix:DI (match_operand:DD 1 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"dctfix %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
;; Convert a decimal128 to a decimal128 whose value is an integer.
|
||||
;; This is the first stage of converting it to an integer type.
|
||||
|
||||
(define_insn "ftrunctd2"
|
||||
[(set (match_operand:TD 0 "gpc_reg_operand" "=f")
|
||||
(fix:TD (match_operand:TD 1 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"drintnq. 0,%0,%1,1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
;; Convert a decimal128 whose value is an integer to an actual integer.
|
||||
;; This is the second stage of converting decimal float to integer type.
|
||||
|
||||
(define_insn "fixtddi2"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=f")
|
||||
(fix:DI (match_operand:TD 1 "gpc_reg_operand" "f")))]
|
||||
"TARGET_DFP"
|
||||
"dctfixq %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
|
|
@ -204,7 +204,9 @@
|
|||
(TF "!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
|
||||
&& TARGET_LONG_DOUBLE_128")])
|
||||
&& TARGET_LONG_DOUBLE_128")
|
||||
(DD "TARGET_DFP")
|
||||
(TD "TARGET_DFP")])
|
||||
|
||||
; Various instructions that come in SI and DI forms.
|
||||
; A generic w/d attribute, for things like cmpw/cmpd.
|
||||
|
|
|
@ -3295,8 +3295,8 @@
|
|||
REAL_VALUE_TYPE cmp, sub;
|
||||
|
||||
operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
|
||||
real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1);
|
||||
real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode));
|
||||
real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1, <BFP:mode>mode);
|
||||
real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode), <BFP:mode>mode);
|
||||
|
||||
emit_insn (gen_cmp<BFP:mode> (operands[1],
|
||||
CONST_DOUBLE_FROM_REAL_VALUE (cmp, <BFP:MODE>mode)));
|
||||
|
|
|
@ -64,8 +64,8 @@ check_real_for_fixed_mode (REAL_VALUE_TYPE *real_value, enum machine_mode mode)
|
|||
{
|
||||
REAL_VALUE_TYPE max_value, min_value, epsilon_value;
|
||||
|
||||
real_2expN (&max_value, GET_MODE_IBIT (mode));
|
||||
real_2expN (&epsilon_value, -GET_MODE_FBIT (mode));
|
||||
real_2expN (&max_value, GET_MODE_IBIT (mode), mode);
|
||||
real_2expN (&epsilon_value, -GET_MODE_FBIT (mode), mode);
|
||||
|
||||
if (SIGNED_FIXED_POINT_MODE_P (mode))
|
||||
min_value = REAL_VALUE_NEGATE (max_value);
|
||||
|
@ -102,7 +102,7 @@ fixed_from_string (FIXED_VALUE_TYPE *f, const char *str, enum machine_mode mode)
|
|||
|| (temp == FIXED_MAX_EPS && ALL_ACCUM_MODE_P (f->mode)))
|
||||
warning (OPT_Woverflow,
|
||||
"large fixed-point constant implicitly truncated to fixed-point type");
|
||||
real_2expN (&base_value, fbit);
|
||||
real_2expN (&base_value, fbit, mode);
|
||||
real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value);
|
||||
real_to_integer2 ((HOST_WIDE_INT *)&f->data.low, &f->data.high,
|
||||
&fixed_value);
|
||||
|
@ -132,7 +132,7 @@ fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *f_orig,
|
|||
{
|
||||
REAL_VALUE_TYPE real_value, base_value, fixed_value;
|
||||
|
||||
real_2expN (&base_value, GET_MODE_FBIT (f_orig->mode));
|
||||
real_2expN (&base_value, GET_MODE_FBIT (f_orig->mode), f_orig->mode);
|
||||
real_from_integer (&real_value, VOIDmode, f_orig->data.low, f_orig->data.high,
|
||||
UNSIGNED_FIXED_POINT_MODE_P (f_orig->mode));
|
||||
real_arithmetic (&fixed_value, RDIV_EXPR, &real_value, &base_value);
|
||||
|
@ -1067,7 +1067,7 @@ fixed_convert_from_real (FIXED_VALUE_TYPE *f, enum machine_mode mode,
|
|||
|
||||
real_value = *a;
|
||||
f->mode = mode;
|
||||
real_2expN (&base_value, fbit);
|
||||
real_2expN (&base_value, fbit, mode);
|
||||
real_arithmetic (&fixed_value, MULT_EXPR, &real_value, &base_value);
|
||||
real_to_integer2 ((HOST_WIDE_INT *)&f->data.low, &f->data.high, &fixed_value);
|
||||
temp = check_real_for_fixed_mode (&real_value, mode);
|
||||
|
@ -1116,7 +1116,7 @@ real_convert_from_fixed (REAL_VALUE_TYPE *r, enum machine_mode mode,
|
|||
{
|
||||
REAL_VALUE_TYPE base_value, fixed_value, real_value;
|
||||
|
||||
real_2expN (&base_value, GET_MODE_FBIT (f->mode));
|
||||
real_2expN (&base_value, GET_MODE_FBIT (f->mode), f->mode);
|
||||
real_from_integer (&fixed_value, VOIDmode, f->data.low, f->data.high,
|
||||
UNSIGNED_FIXED_POINT_MODE_P (f->mode));
|
||||
real_arithmetic (&real_value, RDIV_EXPR, &fixed_value, &base_value);
|
||||
|
|
24
gcc/optabs.c
24
gcc/optabs.c
|
@ -5135,10 +5135,11 @@ expand_float (rtx to, rtx from, int unsignedp)
|
|||
}
|
||||
}
|
||||
|
||||
/* Unsigned integer, and no way to convert directly. For binary
|
||||
floating point modes, convert as signed, then conditionally adjust
|
||||
the result. */
|
||||
if (unsignedp && can_do_signed && !DECIMAL_FLOAT_MODE_P (GET_MODE (to)))
|
||||
/* Unsigned integer, and no way to convert directly. Convert as signed,
|
||||
then unconditionally adjust the result. For decimal float values we
|
||||
do this only if we have already determined that a signed conversion
|
||||
provides sufficient accuracy. */
|
||||
if (unsignedp && (can_do_signed || !DECIMAL_FLOAT_MODE_P (GET_MODE (to))))
|
||||
{
|
||||
rtx label = gen_label_rtx ();
|
||||
rtx temp;
|
||||
|
@ -5229,7 +5230,7 @@ expand_float (rtx to, rtx from, int unsignedp)
|
|||
0, label);
|
||||
|
||||
|
||||
real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
|
||||
real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)), fmode);
|
||||
temp = expand_binop (fmode, add_optab, target,
|
||||
CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
|
||||
target, 0, OPTAB_LIB_WIDEN);
|
||||
|
@ -5340,14 +5341,16 @@ expand_fix (rtx to, rtx from, int unsignedp)
|
|||
anything with a wider integer mode.
|
||||
|
||||
This code used to extend FP value into mode wider than the destination.
|
||||
This is not needed. Consider, for instance conversion from SFmode
|
||||
This is needed for decimal float modes which cannot accurately
|
||||
represent one plus the highest signed number of the same size, but
|
||||
not for binary modes. Consider, for instance conversion from SFmode
|
||||
into DImode.
|
||||
|
||||
The hot path through the code is dealing with inputs smaller than 2^63
|
||||
and doing just the conversion, so there is no bits to lose.
|
||||
|
||||
In the other path we know the value is positive in the range 2^63..2^64-1
|
||||
inclusive. (as for other imput overflow happens and result is undefined)
|
||||
inclusive. (as for other input overflow happens and result is undefined)
|
||||
So we know that the most important bit set in mantissa corresponds to
|
||||
2^63. The subtraction of 2^63 should not generate any rounding as it
|
||||
simply clears out that bit. The rest is trivial. */
|
||||
|
@ -5355,15 +5358,16 @@ expand_fix (rtx to, rtx from, int unsignedp)
|
|||
if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
|
||||
for (fmode = GET_MODE (from); fmode != VOIDmode;
|
||||
fmode = GET_MODE_WIDER_MODE (fmode))
|
||||
if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
|
||||
&must_trunc))
|
||||
if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
|
||||
&& (!DECIMAL_FLOAT_MODE_P (fmode)
|
||||
|| GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))))
|
||||
{
|
||||
int bitsize;
|
||||
REAL_VALUE_TYPE offset;
|
||||
rtx limit, lab1, lab2, insn;
|
||||
|
||||
bitsize = GET_MODE_BITSIZE (GET_MODE (to));
|
||||
real_2expN (&offset, bitsize - 1);
|
||||
real_2expN (&offset, bitsize - 1, fmode);
|
||||
limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
|
||||
lab1 = gen_label_rtx ();
|
||||
lab2 = gen_label_rtx ();
|
||||
|
|
|
@ -2304,7 +2304,7 @@ real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode)
|
|||
/* Fills R with 2**N. */
|
||||
|
||||
void
|
||||
real_2expN (REAL_VALUE_TYPE *r, int n)
|
||||
real_2expN (REAL_VALUE_TYPE *r, int n, enum machine_mode fmode)
|
||||
{
|
||||
memset (r, 0, sizeof (*r));
|
||||
|
||||
|
@ -2319,6 +2319,8 @@ real_2expN (REAL_VALUE_TYPE *r, int n)
|
|||
SET_REAL_EXP (r, n);
|
||||
r->sig[SIGSZ-1] = SIG_MSB;
|
||||
}
|
||||
if (DECIMAL_FLOAT_MODE_P (fmode))
|
||||
decimal_real_convert (r, fmode, r);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -248,7 +248,7 @@ extern bool real_nan (REAL_VALUE_TYPE *, const char *, int, enum machine_mode);
|
|||
|
||||
extern void real_maxval (REAL_VALUE_TYPE *, int, enum machine_mode);
|
||||
|
||||
extern void real_2expN (REAL_VALUE_TYPE *, int);
|
||||
extern void real_2expN (REAL_VALUE_TYPE *, int, enum machine_mode);
|
||||
|
||||
extern unsigned int real_hash (const REAL_VALUE_TYPE *);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue