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:
Janis Johnson 2007-09-07 16:42:48 +00:00 committed by Janis Johnson
parent b48d035854
commit 6ef9a246ce
13 changed files with 231 additions and 29 deletions

View file

@ -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.

View file

@ -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:

View file

@ -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);

View file

@ -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 */

View file

@ -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;

View file

@ -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 ();

View file

@ -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")])

View file

@ -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.

View file

@ -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)));

View file

@ -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);

View file

@ -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 ();

View file

@ -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);
}

View file

@ -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 *);