+2006-01-10 Ben Elliston <bje@au.ibm.com>
+
+ * config/rs6000/predicates.md (easy_fp_constant): Discount decimal
+ float modes.
+ * config/rs6000/rs6000.c (rs6000_scalar_mode_supported_p): New.
+ (TARGET_SCALAR_MODE_SUPPORTED_P): Define.
+ (USE_FP_FOR_ARG): Reject decimal float modes.
+ (function_arg_advance): Likewise.
+ (output_toc): Handle emitting TDmode, DDmode and SDmode constants.
+ (rs6000_handle_altivec_attribute): Do not permit decimal floating
+ point types in AltiVec vectors.
+ (rs6000_function_value): Use GP_ARG_RETURN for decimal floats.
+ (rs6000_libcall_value): Likewise.
+
+2006-01-10 Ben Elliston <bje@au.ibm.com>
+
+ * expr.c (emit_move_change_mode): Always adjust addresses, not
+ just during reload. Copy replacements only during reload.
+ (emit_move_insn_1): Move MODE_DECIMAL_FLOAT modes by invoking
+ emit_move_via_integer.
+
2006-01-09 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/ieee754-df.S: New file.
* config/i386/sse.md (*vec_extractv2di_1_sse2): New.
(*vec_extractv2di_1_sse): New.
+2006-01-09 Ben Elliston <bje@au.ibm.com>
+
+ * doc/tm.texi (Data Output): Add REAL_VALUE_TO_TARGET_DECIMAL32,
+ REAL_VALUE_TO_TARGET_DECIMAL64 and REAL_VALUE_TO_TARGET_DECIMAL64
+ macros.
+
2006-01-09 Ben Elliston <bje@au.ibm.com>
* config/rs6000/rs6000.h (GO_IF_LEGITIMATE_ADDRESS): Typo fix.
/* Subroutines used for code generation on IBM RS/6000.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+ Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GCC.
static tree rs6000_build_builtin_va_list (void);
static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
static bool rs6000_must_pass_in_stack (enum machine_mode, tree);
+static bool rs6000_scalar_mode_supported_p (enum machine_mode);
static bool rs6000_vector_mode_supported_p (enum machine_mode);
static int get_vec_cmp_insn (enum rtx_code, enum machine_mode,
enum machine_mode);
#undef TARGET_EH_RETURN_FILTER_MODE
#define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
+#undef TARGET_SCALAR_MODE_SUPPORTED_P
+#define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
+
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
/* Nonzero if we can use a floating-point register to pass this arg. */
#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
(SCALAR_FLOAT_MODE_P (MODE) \
+ && !DECIMAL_FLOAT_MODE_P (MODE) \
&& (CUM)->fregno <= FP_ARG_MAX_REG \
&& TARGET_HARD_FLOAT && TARGET_FPRS)
cum->words = align_words + n_words;
if (SCALAR_FLOAT_MODE_P (mode)
+ && !DECIMAL_FLOAT_MODE_P (mode)
&& TARGET_HARD_FLOAT && TARGET_FPRS)
cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
/* Handle FP constants specially. Note that if we have a minimal
TOC, things we put here aren't actually in the TOC, so we can allow
FP constants. */
- if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == TFmode)
+ if (GET_CODE (x) == CONST_DOUBLE &&
+ (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
{
REAL_VALUE_TYPE rv;
long k[4];
REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
+ if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
+ REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
+ else
+ REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
if (TARGET_64BIT)
{
return;
}
}
- else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
+ else if (GET_CODE (x) == CONST_DOUBLE &&
+ (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
{
REAL_VALUE_TYPE rv;
long k[2];
REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
- REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
+
+ if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
+ REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
+ else
+ REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
if (TARGET_64BIT)
{
return;
}
}
- else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
+ else if (GET_CODE (x) == CONST_DOUBLE &&
+ (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
{
REAL_VALUE_TYPE rv;
long l;
REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
- REAL_VALUE_TO_TARGET_SINGLE (rv, l);
+ if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
+ REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
+ else
+ REAL_VALUE_TO_TARGET_SINGLE (rv, l);
if (TARGET_64BIT)
{
error ("use of boolean types in AltiVec types is invalid");
else if (TREE_CODE (type) == COMPLEX_TYPE)
error ("use of %<complex%> in AltiVec types is invalid");
+ else if (DECIMAL_FLOAT_MODE_P (mode))
+ error ("use of decimal floating point types in AltiVec types is invalid");
switch (altivec_type)
{
else
mode = TYPE_MODE (valtype);
- if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ regno = GP_ARG_RETURN;
+ else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
regno = FP_ARG_RETURN;
else if (TREE_CODE (valtype) == COMPLEX_TYPE
&& targetm.calls.split_complex_arg)
GEN_INT (4))));
}
- if (SCALAR_FLOAT_MODE_P (mode)
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ regno = GP_ARG_RETURN;
+ else if (SCALAR_FLOAT_MODE_P (mode)
&& TARGET_HARD_FLOAT && TARGET_FPRS)
regno = FP_ARG_RETURN;
else if (ALTIVEC_VECTOR_MODE (mode)
return TARGET_32BIT ? SImode : word_mode;
}
+/* Target hook for scalar_mode_supported_p. */
+static bool
+rs6000_scalar_mode_supported_p (enum machine_mode mode)
+{
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ return true;
+ else
+ return default_scalar_mode_supported_p (mode);
+}
+
/* Target hook for vector_mode_supported_p. */
static bool
rs6000_vector_mode_supported_p (enum machine_mode mode)