optabs.c (init_floating_libfuncs): Handle decimal float modes.

* optabs.c (init_floating_libfuncs): Handle decimal float modes.
	(init_optabs): Handle libfuncs for decimal float.
	* genopinit.c (gen_insn): Handle MODE_DECIMAL_FLOAT.
	* stor-layout.c (int_mode_for_mode): Likewise.
	* simplify-rtx.c (simplify_immed_subreg): Likewise.
	(simplify_unary_operation_1): Skip optimisations for decimal float
	modes.
	* varasm.c (output_constant_pool_2): Handle MODE_DECIMAL_FLOAT.
	* emit-rtl.c (gen_const_vector): Add assertion check.
	(init_emit_once): Populate const_tiny_rtx with constants in each
	decimal float mode.
	* expmed.c (extract_high_half, expand_mult_highpart_optab,
	expand_mult_highpart): Assert that mode is not a scalar float
	mode.
	* expr.c (convert_move): Handle conversion between decimal and
	binary floats of the same size.
	* convert.c (convert_to_real): Consider decimal float types when
	folding.
	* dwarf2out.c (base_type_die): Use DW_ATE_decimal_float to
	describe decimal floating point types.

Co-Authored-By: Ben Elliston <bje@au.ibm.com>
Co-Authored-By: Janis Johnson <janis187@us.ibm.com>

From-SVN: r108762
This commit is contained in:
Jon Grimm 2005-12-18 21:40:47 +00:00 committed by Ben Elliston
parent 5a575f77fd
commit 15ed7b52cb
11 changed files with 114 additions and 12 deletions

View File

@ -1,3 +1,28 @@
2005-12-17 Jon Grimm <jgrimm2@us.ibm.com>
Janis Johnson <janis187@us.ibm.com>
Ben Elliston <bje@au.ibm.com>
* optabs.c (init_floating_libfuncs): Handle decimal float modes.
(init_optabs): Handle libfuncs for decimal float.
* genopinit.c (gen_insn): Handle MODE_DECIMAL_FLOAT.
* stor-layout.c (int_mode_for_mode): Likewise.
* simplify-rtx.c (simplify_immed_subreg): Likewise.
(simplify_unary_operation_1): Skip optimisations for decimal float
modes.
* varasm.c (output_constant_pool_2): Handle MODE_DECIMAL_FLOAT.
* emit-rtl.c (gen_const_vector): Add assertion check.
(init_emit_once): Populate const_tiny_rtx with constants in each
decimal float mode.
* expmed.c (extract_high_half, expand_mult_highpart_optab,
expand_mult_highpart): Assert that mode is not a scalar float
mode.
* expr.c (convert_move): Handle conversion between decimal and
binary floats of the same size.
* convert.c (convert_to_real): Consider decimal float types when
folding.
* dwarf2out.c (base_type_die): Use DW_ATE_decimal_float to
describe decimal floating point types.
2005-12-18 Ulrich Weigand <uweigand@de.ibm.com>
PR rtl-optimization/21041

View File

@ -263,6 +263,28 @@ convert_to_real (tree type, tree expr)
&& FLOAT_TYPE_P (TREE_TYPE (arg1)))
{
tree newtype = type;
if (TYPE_MODE (TREE_TYPE (arg0)) == SDmode
|| TYPE_MODE (TREE_TYPE (arg1)) == SDmode)
newtype = dfloat32_type_node;
if (TYPE_MODE (TREE_TYPE (arg0)) == DDmode
|| TYPE_MODE (TREE_TYPE (arg1)) == DDmode)
newtype = dfloat64_type_node;
if (TYPE_MODE (TREE_TYPE (arg0)) == TDmode
|| TYPE_MODE (TREE_TYPE (arg1)) == TDmode)
newtype = dfloat128_type_node;
if (newtype == dfloat32_type_node
|| newtype == dfloat64_type_node
|| newtype == dfloat128_type_node)
{
expr = build2 (TREE_CODE (expr), newtype,
fold (convert_to_real (newtype, arg0)),
fold (convert_to_real (newtype, arg1)));
if (newtype == type)
return expr;
break;
}
if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
newtype = TREE_TYPE (arg0);
if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))

View File

@ -8124,7 +8124,10 @@ base_type_die (tree type)
break;
case REAL_TYPE:
encoding = DW_ATE_float;
if (DECIMAL_FLOAT_MODE_P (TYPE_MODE (type)))
encoding = DW_ATE_decimal_float;
else
encoding = DW_ATE_float;
break;
/* Dwarf2 doesn't know anything about complex ints, so use

View File

@ -5151,6 +5151,8 @@ gen_const_vector (enum machine_mode mode, int constant)
units = GET_MODE_NUNITS (mode);
inner = GET_MODE_INNER (mode);
gcc_assert (!DECIMAL_FLOAT_MODE_P (inner));
v = rtvec_alloc (units);
/* We need to call this function after we set the scalar const_tiny_rtx
@ -5227,7 +5229,8 @@ init_emit_once (int line_numbers)
word_mode = VOIDmode;
double_mode = VOIDmode;
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
{
if (GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
@ -5239,7 +5242,8 @@ init_emit_once (int line_numbers)
word_mode = mode;
}
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
{
if (GET_MODE_BITSIZE (mode) == DOUBLE_TYPE_SIZE
@ -5324,14 +5328,22 @@ init_emit_once (int line_numbers)
REAL_VALUE_TYPE *r =
(i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
const_tiny_rtx[i][(int) mode] =
CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
for (mode = GET_CLASS_NARROWEST_MODE (MODE_DECIMAL_FLOAT);
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
const_tiny_rtx[i][(int) mode] =
CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
const_tiny_rtx[i][(int) VOIDmode] = GEN_INT (i);
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
const_tiny_rtx[i][(int) mode] = GEN_INT (i);

View File

@ -3383,6 +3383,8 @@ extract_high_half (enum machine_mode mode, rtx op)
if (mode == word_mode)
return gen_highpart (mode, op);
gcc_assert (!SCALAR_FLOAT_MODE_P (mode));
wider_mode = GET_MODE_WIDER_MODE (mode);
op = expand_shift (RSHIFT_EXPR, wider_mode, op,
build_int_cst (NULL_TREE, GET_MODE_BITSIZE (mode)), 0, 1);
@ -3402,6 +3404,8 @@ expand_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1,
rtx tem;
int size;
gcc_assert (!SCALAR_FLOAT_MODE_P (mode));
wider_mode = GET_MODE_WIDER_MODE (mode);
size = GET_MODE_BITSIZE (mode);
@ -3512,6 +3516,7 @@ expand_mult_highpart (enum machine_mode mode, rtx op0, rtx op1,
struct algorithm alg;
rtx tem;
gcc_assert (!SCALAR_FLOAT_MODE_P (mode));
/* We can't support modes wider than HOST_BITS_PER_INT. */
gcc_assert (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT);

View File

@ -410,10 +410,15 @@ convert_move (rtx to, rtx from, int unsignedp)
rtx value, insns;
convert_optab tab;
gcc_assert (GET_MODE_PRECISION (from_mode)
!= GET_MODE_PRECISION (to_mode));
gcc_assert ((GET_MODE_PRECISION (from_mode)
!= GET_MODE_PRECISION (to_mode))
|| (DECIMAL_FLOAT_MODE_P (from_mode)
!= DECIMAL_FLOAT_MODE_P (to_mode)));
if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode))
if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
/* Conversion between decimal float and binary float, same size. */
tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab;
else if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode))
tab = sext_optab;
else
tab = trunc_optab;

View File

@ -304,7 +304,9 @@ gen_insn (rtx insn)
|| mode_class[i] == MODE_INT
|| mode_class[i] == MODE_PARTIAL_INT
|| mode_class[i] == MODE_VECTOR_INT)
&& (! force_float || mode_class[i] == MODE_FLOAT
&& (! force_float
|| mode_class[i] == MODE_FLOAT
|| mode_class[i] == MODE_DECIMAL_FLOAT
|| mode_class[i] == MODE_COMPLEX_FLOAT
|| mode_class[i] == MODE_VECTOR_FLOAT))
break;

View File

@ -4375,9 +4375,10 @@ expand_float (rtx to, rtx from, int unsignedp)
}
}
/* Unsigned integer, and no way to convert directly.
Convert as signed, then conditionally adjust the result. */
if (unsignedp && can_do_signed)
/* 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)))
{
rtx label = gen_label_rtx ();
rtx temp;
@ -4837,6 +4838,8 @@ static void
init_floating_libfuncs (optab optable, const char *opname, int suffix)
{
init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
init_libfuncs (optable, MIN_MODE_DECIMAL_FLOAT, MAX_MODE_DECIMAL_FLOAT,
opname, suffix);
}
/* Initialize the libfunc fields of an entire group of entries of an
@ -5254,16 +5257,32 @@ init_optabs (void)
/* Conversions. */
init_interclass_conv_libfuncs (sfloat_optab, "float",
MODE_INT, MODE_FLOAT);
init_interclass_conv_libfuncs (sfloat_optab, "float",
MODE_INT, MODE_DECIMAL_FLOAT);
init_interclass_conv_libfuncs (ufloat_optab, "floatun",
MODE_INT, MODE_FLOAT);
init_interclass_conv_libfuncs (ufloat_optab, "floatun",
MODE_INT, MODE_DECIMAL_FLOAT);
init_interclass_conv_libfuncs (sfix_optab, "fix",
MODE_FLOAT, MODE_INT);
init_interclass_conv_libfuncs (sfix_optab, "fix",
MODE_DECIMAL_FLOAT, MODE_INT);
init_interclass_conv_libfuncs (ufix_optab, "fixuns",
MODE_FLOAT, MODE_INT);
init_interclass_conv_libfuncs (ufix_optab, "fixuns",
MODE_DECIMAL_FLOAT, MODE_INT);
init_interclass_conv_libfuncs (ufloat_optab, "floatuns",
MODE_INT, MODE_DECIMAL_FLOAT);
/* sext_optab is also used for FLOAT_EXTEND. */
init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, true);
init_interclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, MODE_DECIMAL_FLOAT);
init_interclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, MODE_FLOAT);
init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, false);
init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, MODE_DECIMAL_FLOAT);
init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, MODE_FLOAT);
/* Use cabs for double complex abs, since systems generally have cabs.
Don't define any libcall for float complex, so that cabs will be used. */

View File

@ -640,6 +640,9 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
break;
case FLOAT_TRUNCATE:
if (DECIMAL_FLOAT_MODE_P (mode))
break;
/* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
if (GET_CODE (op) == FLOAT_EXTEND
&& GET_MODE (XEXP (op, 0)) == mode)
@ -693,6 +696,9 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
break;
case FLOAT_EXTEND:
if (DECIMAL_FLOAT_MODE_P (mode))
break;
/* (float_extend (float_extend x)) is (float_extend x)
(float_extend (float x)) is (float x) assuming that double
@ -4284,6 +4290,7 @@ simplify_immed_subreg (enum machine_mode outermode, rtx op,
break;
case MODE_FLOAT:
case MODE_DECIMAL_FLOAT:
{
REAL_VALUE_TYPE r;
long tmp[max_bitsize / 32];

View File

@ -232,6 +232,7 @@ int_mode_for_mode (enum machine_mode mode)
case MODE_COMPLEX_INT:
case MODE_COMPLEX_FLOAT:
case MODE_FLOAT:
case MODE_DECIMAL_FLOAT:
case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT:
mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);

View File

@ -3077,6 +3077,7 @@ output_constant_pool_2 (enum machine_mode mode, rtx x, unsigned int align)
switch (GET_MODE_CLASS (mode))
{
case MODE_FLOAT:
case MODE_DECIMAL_FLOAT:
{
REAL_VALUE_TYPE r;