mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-24 03:14:08 +08:00
rs6000-c.c (rs6000_cpu_cpp_builtins): Define _SOFT_DOUBLE if doubles use software floating-point.
gcc: * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Define _SOFT_DOUBLE if doubles use software floating-point. * config/rs6000/libgcc-ppc-glibc.ver: Export additional long double functions if _SOFT_DOUBLE, not _SOFT_FLOAT. * config/rs6000/darwin-ldouble.c: Also compile functions for hard-float without FPRs. Use fmsub function for all __NO_FPRS__ cases. Compile extra functions if _SOFT_DOUBLE, not _SOFT_FLOAT. * config/rs6000/linuxspe.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Remove commented-out long double override. (CPP_LONGDOUBLE_DEFAULT_SPEC): Likewise. * config/rs6000/eabispe.h: Likewise. * config/rs6000/rs6000.c (rs6000_override_options): Don't override long double for non-SPE. (rs6000_handle_option): Likewise. (invalid_e500_subreg): Disallow more subregs involding DImode, DFmode, TImode or TFmode. (rs6000_legitimate_offset_address_p): Check TFmode offsets for E500 double. (legitimate_lo_sum_address_p): Also check for TFmode for E500 double. (rs6000_legitimize_address): Also handle TFmode for E500 double. (rs6000_legitimize_reload_address): Also handle TFmode for E500 double. (rs6000_legitimate_address): Also check for TFmode for E500 double. (rs6000_emit_move): Use DFmode subregs of TFmode for E500 double. (spe_build_register_parallel): Handle TFmode and TCmode. (rs6000_spe_function_arg): Handle TFmode and TCmode for E500 double. (function_arg): Handle TFmode and TCmode for E500 double. (rs6000_init_libfuncs): Initialize extra libfuncs for soft double in general. (print_operand): Handle TFmode and TImode for %y. (rs6000_generate_compare): Handle TFmode comparisons for E500 double. (spe_func_has_64bit_regs_p): Check for TFmode for E500 double. (rs6000_function_value): Handle TFmode and TCmode for E500 double. (rs6000_libcall_value): Handle TFmode and TCmode for E500 double. * config/rs6000/rs6000.h (CANNOT_CHANGE_MODE_CLASS): Check for TFmode for E500 double. * config/rs6000/rs6000.md (FP): Allow TF for E500 double. (floatsidf2): Enable for E500 double. (movtf_softfloat): Use rs6000_nonimmediate_operand. (extenddftf2): Change to extenddftf2_fprs. (extenddftf2): Call gen_spe_extenddftf2 or gen_extenddftf2_fprs depending on TARGET_E500_DOUBLE. (extendsftf2): Enable for E500 double. (trunctfdf2): Enable for E500 double. (trunctfsf2): Change to trunctfsf2_fprs. (trunctfsf2): Call gen_spe_trunctfsf2 or gen_trunctfsf2_fprs depending on TARGET_E500_DOUBLE. (floatsitf2): Enable for E500 double. (fix_trunctfsi2): Change to fix_trunctfsi2_fprs. (fix_trunctfsi2): Call gen_spe_fix_trunctfsi2 or gen_fix_trunctfsi2_fprs depending on TARGET_E500_DOUBLE. (negtf2): Change to negtf2_internal. (negtf2): New expander. (abstf2): Enable for E500 double. Call gen_spe_abstf2_tst, gen_spe_abstf2_cmp or gen_abstf2_internal depending on TARGET_E500_DOUBLE and flag_unsafe_math_optimizations. (movdi_internal32): Use rs6000_nonimmediate_operand. (unnamed splitter): Likewise. * config/rs6000/spe.md (CMPTFEQ_GPR, TSTTFEQ_GPR, CMPTFGT_GPR, TSTTFGT_GPR, CMPTFLT_GPR, TSTTFLT_GPR): New unspecs. (SPE64TF, DITI): New mode macros. (frob_df_di): Change to frob_<SPE64:mode>_<DITI:mode>; allow more modes. (frob_tf_ti): New. (frob_<mode>_di_2): New. (frob_tf_di_8_2): New. (frob_di_df): Change to frob_di_<mode>; allow more modes. (frob_ti_tf): New. (frob_di_df_2): Change to frob_<DITI:mode>_<SPE64:mode>_2; allow more modes. (frob_ti_<mode>_8_2): New. (frob_ti_tf_2): New. (mov_si<mode>_e500_subreg0, mov_si<mode>_e500_subreg0_2, mov_si<mode>_e500_subreg4, mov_si<mode>_e500_subreg4_2): Allow TFmode. (mov_sitf_e500_subreg8, mov_sitf_e500_subreg8_2, mov_sitf_e500_subreg12, mov_sitf_e500_subreg12_2): New. (spe_trunctfdf2_internal1, spe_trunctfsf2, spe_extenddftf2, spe_fix_trunctfsi2, spe_fix_trunctfsi2_internal, spe_negtf2_internal, spe_abstf2_cmp, spe_abstf2_tst): New. (cmptfeq_gpr, tsttfeq_gpr, cmptfgt_gpr, tsttfgt_gpr, cmptflt_gpr, tsttflt_gp): New. libgcc: * config/rs6000/t-ldbl128: Always use -mlong-double-128. From-SVN: r121085
This commit is contained in:
parent
dc5696215d
commit
17caeff262
@ -1,3 +1,92 @@
|
||||
2007-01-23 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Define
|
||||
_SOFT_DOUBLE if doubles use software floating-point.
|
||||
* config/rs6000/libgcc-ppc-glibc.ver: Export additional long
|
||||
double functions if _SOFT_DOUBLE, not _SOFT_FLOAT.
|
||||
* config/rs6000/darwin-ldouble.c: Also compile functions for
|
||||
hard-float without FPRs. Use fmsub function for all __NO_FPRS__
|
||||
cases. Compile extra functions if _SOFT_DOUBLE, not _SOFT_FLOAT.
|
||||
* config/rs6000/linuxspe.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Remove
|
||||
commented-out long double override.
|
||||
(CPP_LONGDOUBLE_DEFAULT_SPEC): Likewise.
|
||||
* config/rs6000/eabispe.h: Likewise.
|
||||
* config/rs6000/rs6000.c (rs6000_override_options): Don't override
|
||||
long double for non-SPE.
|
||||
(rs6000_handle_option): Likewise.
|
||||
(invalid_e500_subreg): Disallow more subregs involding DImode,
|
||||
DFmode, TImode or TFmode.
|
||||
(rs6000_legitimate_offset_address_p): Check TFmode offsets for
|
||||
E500 double.
|
||||
(legitimate_lo_sum_address_p): Also check for TFmode for E500
|
||||
double.
|
||||
(rs6000_legitimize_address): Also handle TFmode for E500 double.
|
||||
(rs6000_legitimize_reload_address): Also handle TFmode for E500
|
||||
double.
|
||||
(rs6000_legitimate_address): Also check for TFmode for E500
|
||||
double.
|
||||
(rs6000_emit_move): Use DFmode subregs of TFmode for E500 double.
|
||||
(spe_build_register_parallel): Handle TFmode and TCmode.
|
||||
(rs6000_spe_function_arg): Handle TFmode and TCmode for E500
|
||||
double.
|
||||
(function_arg): Handle TFmode and TCmode for E500 double.
|
||||
(rs6000_init_libfuncs): Initialize extra libfuncs for soft double
|
||||
in general.
|
||||
(print_operand): Handle TFmode and TImode for %y.
|
||||
(rs6000_generate_compare): Handle TFmode comparisons for E500
|
||||
double.
|
||||
(spe_func_has_64bit_regs_p): Check for TFmode for E500 double.
|
||||
(rs6000_function_value): Handle TFmode and TCmode for E500 double.
|
||||
(rs6000_libcall_value): Handle TFmode and TCmode for E500 double.
|
||||
* config/rs6000/rs6000.h (CANNOT_CHANGE_MODE_CLASS): Check for
|
||||
TFmode for E500 double.
|
||||
* config/rs6000/rs6000.md (FP): Allow TF for E500 double.
|
||||
(floatsidf2): Enable for E500 double.
|
||||
(movtf_softfloat): Use rs6000_nonimmediate_operand.
|
||||
(extenddftf2): Change to extenddftf2_fprs.
|
||||
(extenddftf2): Call gen_spe_extenddftf2 or gen_extenddftf2_fprs
|
||||
depending on TARGET_E500_DOUBLE.
|
||||
(extendsftf2): Enable for E500 double.
|
||||
(trunctfdf2): Enable for E500 double.
|
||||
(trunctfsf2): Change to trunctfsf2_fprs.
|
||||
(trunctfsf2): Call gen_spe_trunctfsf2 or gen_trunctfsf2_fprs
|
||||
depending on TARGET_E500_DOUBLE.
|
||||
(floatsitf2): Enable for E500 double.
|
||||
(fix_trunctfsi2): Change to fix_trunctfsi2_fprs.
|
||||
(fix_trunctfsi2): Call gen_spe_fix_trunctfsi2 or
|
||||
gen_fix_trunctfsi2_fprs depending on TARGET_E500_DOUBLE.
|
||||
(negtf2): Change to negtf2_internal.
|
||||
(negtf2): New expander.
|
||||
(abstf2): Enable for E500 double. Call gen_spe_abstf2_tst,
|
||||
gen_spe_abstf2_cmp or gen_abstf2_internal depending on
|
||||
TARGET_E500_DOUBLE and flag_unsafe_math_optimizations.
|
||||
(movdi_internal32): Use rs6000_nonimmediate_operand.
|
||||
(unnamed splitter): Likewise.
|
||||
* config/rs6000/spe.md (CMPTFEQ_GPR, TSTTFEQ_GPR, CMPTFGT_GPR,
|
||||
TSTTFGT_GPR, CMPTFLT_GPR, TSTTFLT_GPR): New unspecs.
|
||||
(SPE64TF, DITI): New mode macros.
|
||||
(frob_df_di): Change to frob_<SPE64:mode>_<DITI:mode>; allow more
|
||||
modes.
|
||||
(frob_tf_ti): New.
|
||||
(frob_<mode>_di_2): New.
|
||||
(frob_tf_di_8_2): New.
|
||||
(frob_di_df): Change to frob_di_<mode>; allow more modes.
|
||||
(frob_ti_tf): New.
|
||||
(frob_di_df_2): Change to frob_<DITI:mode>_<SPE64:mode>_2; allow
|
||||
more modes.
|
||||
(frob_ti_<mode>_8_2): New.
|
||||
(frob_ti_tf_2): New.
|
||||
(mov_si<mode>_e500_subreg0, mov_si<mode>_e500_subreg0_2,
|
||||
mov_si<mode>_e500_subreg4, mov_si<mode>_e500_subreg4_2): Allow
|
||||
TFmode.
|
||||
(mov_sitf_e500_subreg8, mov_sitf_e500_subreg8_2,
|
||||
mov_sitf_e500_subreg12, mov_sitf_e500_subreg12_2): New.
|
||||
(spe_trunctfdf2_internal1, spe_trunctfsf2, spe_extenddftf2,
|
||||
spe_fix_trunctfsi2, spe_fix_trunctfsi2_internal,
|
||||
spe_negtf2_internal, spe_abstf2_cmp, spe_abstf2_tst): New.
|
||||
(cmptfeq_gpr, tsttfeq_gpr, cmptfgt_gpr, tsttfgt_gpr, cmptflt_gpr,
|
||||
tsttflt_gp): New.
|
||||
|
||||
2007-01-23 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* Makefile.in (OBJS-common): Reformat, alphabetize, but put
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* 128-bit long double support routines for Darwin.
|
||||
Copyright (C) 1993, 2003, 2004, 2005, 2006
|
||||
Copyright (C) 1993, 2003, 2004, 2005, 2006, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -49,8 +49,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
|
||||
This code currently assumes big-endian. */
|
||||
|
||||
#if ((!defined (__NO_FPRS__) || defined (_SOFT_FLOAT)) \
|
||||
&& !defined (__LITTLE_ENDIAN__) \
|
||||
#if (!defined (__LITTLE_ENDIAN__) \
|
||||
&& (defined (__MACH__) || defined (__powerpc__) || defined (_AIX)))
|
||||
|
||||
#define fabs(x) __builtin_fabs(x)
|
||||
@ -145,7 +144,7 @@ __gcc_qsub (double a, double b, double c, double d)
|
||||
return __gcc_qadd (a, b, -c, -d);
|
||||
}
|
||||
|
||||
#ifdef _SOFT_FLOAT
|
||||
#ifdef __NO_FPRS__
|
||||
static double fmsub (double, double, double);
|
||||
#endif
|
||||
|
||||
@ -164,7 +163,7 @@ __gcc_qmul (double a, double b, double c, double d)
|
||||
/* Sum terms of two highest orders. */
|
||||
|
||||
/* Use fused multiply-add to get low part of a * c. */
|
||||
#ifndef _SOFT_FLOAT
|
||||
#ifndef __NO_FPRS__
|
||||
asm ("fmsub %0,%1,%2,%3" : "=f"(tau) : "f"(a), "f"(c), "f"(t));
|
||||
#else
|
||||
tau = fmsub (a, c, t);
|
||||
@ -201,7 +200,7 @@ __gcc_qdiv (double a, double b, double c, double d)
|
||||
numerically necessary. */
|
||||
|
||||
/* Use fused multiply-add to get low part of c * t. */
|
||||
#ifndef _SOFT_FLOAT
|
||||
#ifndef __NO_FPRS__
|
||||
asm ("fmsub %0,%1,%2,%3" : "=f"(sigma) : "f"(c), "f"(t), "f"(s));
|
||||
#else
|
||||
sigma = fmsub (c, t, s);
|
||||
@ -219,7 +218,7 @@ __gcc_qdiv (double a, double b, double c, double d)
|
||||
return z.ldval;
|
||||
}
|
||||
|
||||
#if defined (_SOFT_FLOAT) && defined (__LONG_DOUBLE_128__)
|
||||
#if defined (_SOFT_DOUBLE) && defined (__LONG_DOUBLE_128__)
|
||||
|
||||
long double __gcc_qneg (double, double);
|
||||
int __gcc_qeq (double, double, double, double);
|
||||
@ -362,6 +361,10 @@ __gcc_utoq (unsigned int a)
|
||||
return __gcc_dtoq ((double) a);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __NO_FPRS__
|
||||
|
||||
#include "config/soft-fp/soft-fp.h"
|
||||
#include "config/soft-fp/double.h"
|
||||
#include "config/soft-fp/quad.h"
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Core target definitions for GNU compiler
|
||||
for PowerPC embedded targeted systems with SPE support.
|
||||
Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Aldy Hernandez (aldyh@redhat.com).
|
||||
|
||||
This file is part of GCC.
|
||||
@ -35,9 +36,6 @@
|
||||
rs6000_spe_abi = 1; \
|
||||
if (!rs6000_explicit_options.float_gprs) \
|
||||
rs6000_float_gprs = 1; \
|
||||
/* See note below. */ \
|
||||
/*if (!rs6000_explicit_options.long_double)*/ \
|
||||
/* rs6000_long_double_type_size = 128;*/ \
|
||||
if (!rs6000_explicit_options.spe) \
|
||||
rs6000_spe = 1; \
|
||||
if (!rs6000_explicit_options.isel) \
|
||||
@ -52,8 +50,7 @@
|
||||
specifications, until I properly fix the emulation.
|
||||
|
||||
Enable these later.
|
||||
#undef CPP_LONGDOUBLE_DEFAULT_SPEC
|
||||
#define CPP_LONGDOUBLE_DEFAULT_SPEC "-D__LONG_DOUBLE_128__=1"
|
||||
#define RS6000_DEFAULT_LONG_DOUBLE_SIZE (TARGET_SPE ? 128 : 64)
|
||||
*/
|
||||
|
||||
#undef ASM_DEFAULT_SPEC
|
||||
|
@ -31,7 +31,7 @@ GCC_4.2.0 {
|
||||
__gcc_qmul
|
||||
__gcc_qdiv
|
||||
|
||||
%ifdef _SOFT_FLOAT
|
||||
%ifdef _SOFT_DOUBLE
|
||||
__gcc_qneg
|
||||
__gcc_qeq
|
||||
__gcc_qne
|
||||
|
@ -35,9 +35,6 @@
|
||||
rs6000_spe_abi = 1; \
|
||||
if (!rs6000_explicit_options.float_gprs) \
|
||||
rs6000_float_gprs = 1; \
|
||||
/* See note below. */ \
|
||||
/*if (!rs6000_explicit_options.long_double)*/ \
|
||||
/* rs6000_long_double_type_size = 128;*/ \
|
||||
if (!rs6000_explicit_options.spe) \
|
||||
rs6000_spe = 1; \
|
||||
if (!rs6000_explicit_options.isel) \
|
||||
@ -45,16 +42,5 @@
|
||||
if (target_flags & MASK_64BIT) \
|
||||
error ("-m64 not supported in this configuration")
|
||||
|
||||
/* The e500 ABI says that either long doubles are 128 bits, or if
|
||||
implemented in any other size, the compiler/linker should error out.
|
||||
We have no emulation libraries for 128 bit long doubles, and I hate
|
||||
the dozens of failures on the regression suite. So I'm breaking ABI
|
||||
specifications, until I properly fix the emulation.
|
||||
|
||||
Enable these later.
|
||||
#undef CPP_LONGDOUBLE_DEFAULT_SPEC
|
||||
#define CPP_LONGDOUBLE_DEFAULT_SPEC "-D__LONG_DOUBLE_128__=1"
|
||||
*/
|
||||
|
||||
#undef ASM_DEFAULT_SPEC
|
||||
#define ASM_DEFAULT_SPEC "-mppc -mspe -me500"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Subroutines for the C front end on the POWER and PowerPC architectures.
|
||||
Copyright (C) 2002, 2003, 2004, 2005
|
||||
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Zack Weinberg <zack@codesourcery.com>
|
||||
@ -124,6 +124,8 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
|
||||
builtin_define ("__SPE__");
|
||||
if (TARGET_SOFT_FLOAT)
|
||||
builtin_define ("_SOFT_FLOAT");
|
||||
if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
|
||||
builtin_define ("_SOFT_DOUBLE");
|
||||
/* Used by lwarx/stwcx. errata work-around. */
|
||||
if (rs6000_cpu == PROCESSOR_PPC405)
|
||||
builtin_define ("__PPC405__");
|
||||
|
@ -1464,8 +1464,6 @@ rs6000_override_options (const char *default_cpu)
|
||||
rs6000_float_gprs = 0;
|
||||
if (!rs6000_explicit_options.isel)
|
||||
rs6000_isel = 0;
|
||||
if (!rs6000_explicit_options.long_double)
|
||||
rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
|
||||
}
|
||||
|
||||
/* Detect invalid option combinations with E500. */
|
||||
@ -1892,9 +1890,6 @@ rs6000_handle_option (size_t code, const char *arg, int value)
|
||||
case OPT_mspe_:
|
||||
rs6000_explicit_options.spe = true;
|
||||
rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
|
||||
/* No SPE means 64-bit long doubles, even if an E500. */
|
||||
if (!rs6000_spe)
|
||||
rs6000_long_double_type_size = 64;
|
||||
break;
|
||||
|
||||
case OPT_mdebug_:
|
||||
@ -2718,18 +2713,22 @@ invalid_e500_subreg (rtx op, enum machine_mode mode)
|
||||
{
|
||||
if (TARGET_E500_DOUBLE)
|
||||
{
|
||||
/* Reject (subreg:SI (reg:DF)). */
|
||||
/* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
|
||||
subreg:TI and reg:TF. */
|
||||
if (GET_CODE (op) == SUBREG
|
||||
&& mode == SImode
|
||||
&& (mode == SImode || mode == DImode || mode == TImode)
|
||||
&& REG_P (SUBREG_REG (op))
|
||||
&& GET_MODE (SUBREG_REG (op)) == DFmode)
|
||||
&& (GET_MODE (SUBREG_REG (op)) == DFmode
|
||||
|| GET_MODE (SUBREG_REG (op)) == TFmode))
|
||||
return true;
|
||||
|
||||
/* Reject (subreg:DF (reg:DI)). */
|
||||
/* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
|
||||
reg:TI. */
|
||||
if (GET_CODE (op) == SUBREG
|
||||
&& mode == DFmode
|
||||
&& (mode == DFmode || mode == TFmode)
|
||||
&& REG_P (SUBREG_REG (op))
|
||||
&& GET_MODE (SUBREG_REG (op)) == DImode)
|
||||
&& (GET_MODE (SUBREG_REG (op)) == DImode
|
||||
|| GET_MODE (SUBREG_REG (op)) == TImode))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2989,6 +2988,10 @@ rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
|
||||
break;
|
||||
|
||||
case TFmode:
|
||||
if (TARGET_E500_DOUBLE)
|
||||
return (SPE_CONST_OFFSET_OK (offset)
|
||||
&& SPE_CONST_OFFSET_OK (offset + 8));
|
||||
|
||||
case TImode:
|
||||
if (mode == TFmode || !TARGET_POWERPC64)
|
||||
extra = 12;
|
||||
@ -3067,7 +3070,8 @@ legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
|
||||
if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
|
||||
return false;
|
||||
/* Restrict addressing for DI because of our SUBREG hackery. */
|
||||
if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
|
||||
if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
|
||||
|| mode == DImode))
|
||||
return false;
|
||||
x = XEXP (x, 1);
|
||||
|
||||
@ -3165,7 +3169,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
||||
return reg;
|
||||
}
|
||||
else if (SPE_VECTOR_MODE (mode)
|
||||
|| (TARGET_E500_DOUBLE && (mode == DFmode
|
||||
|| (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
|
||||
|| mode == DImode)))
|
||||
{
|
||||
if (mode == DImode)
|
||||
@ -3570,7 +3574,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
|
||||
&& REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
|
||||
&& GET_CODE (XEXP (x, 1)) == CONST_INT
|
||||
&& !SPE_VECTOR_MODE (mode)
|
||||
&& !(TARGET_E500_DOUBLE && (mode == DFmode
|
||||
&& !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
|
||||
|| mode == DImode))
|
||||
&& !ALTIVEC_VECTOR_MODE (mode))
|
||||
{
|
||||
@ -3707,7 +3711,8 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
|
||||
&& !SPE_VECTOR_MODE (mode)
|
||||
&& mode != TFmode
|
||||
/* Restrict addressing for DI because of our SUBREG hackery. */
|
||||
&& !(TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
|
||||
&& !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
|
||||
|| mode == DImode))
|
||||
&& TARGET_UPDATE
|
||||
&& legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
|
||||
return 1;
|
||||
@ -4222,14 +4227,15 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
|
||||
{
|
||||
/* DImode is used, not DFmode, because simplify_gen_subreg doesn't
|
||||
know how to get a DFmode SUBREG of a TFmode. */
|
||||
rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0),
|
||||
simplify_gen_subreg (DImode, operands[1], mode, 0),
|
||||
DImode);
|
||||
rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode,
|
||||
GET_MODE_SIZE (DImode)),
|
||||
simplify_gen_subreg (DImode, operands[1], mode,
|
||||
GET_MODE_SIZE (DImode)),
|
||||
DImode);
|
||||
enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
|
||||
rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
|
||||
simplify_gen_subreg (imode, operands[1], mode, 0),
|
||||
imode);
|
||||
rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
|
||||
GET_MODE_SIZE (imode)),
|
||||
simplify_gen_subreg (imode, operands[1], mode,
|
||||
GET_MODE_SIZE (imode)),
|
||||
imode);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5019,7 +5025,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
static rtx
|
||||
spe_build_register_parallel (enum machine_mode mode, int gregno)
|
||||
{
|
||||
rtx r1, r3;
|
||||
rtx r1, r3, r5, r7;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
@ -5029,12 +5035,24 @@ spe_build_register_parallel (enum machine_mode mode, int gregno)
|
||||
return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
|
||||
|
||||
case DCmode:
|
||||
case TFmode:
|
||||
r1 = gen_rtx_REG (DImode, gregno);
|
||||
r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
|
||||
r3 = gen_rtx_REG (DImode, gregno + 2);
|
||||
r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
|
||||
return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
|
||||
|
||||
case TCmode:
|
||||
r1 = gen_rtx_REG (DImode, gregno);
|
||||
r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
|
||||
r3 = gen_rtx_REG (DImode, gregno + 2);
|
||||
r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
|
||||
r5 = gen_rtx_REG (DImode, gregno + 4);
|
||||
r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
|
||||
r7 = gen_rtx_REG (DImode, gregno + 6);
|
||||
r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
|
||||
return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
@ -5049,7 +5067,8 @@ rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
|
||||
/* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
|
||||
are passed and returned in a pair of GPRs for ABI compatibility. */
|
||||
if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode))
|
||||
if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode
|
||||
|| mode == TFmode || mode == TCmode))
|
||||
{
|
||||
int n_words = rs6000_arg_size (mode, type);
|
||||
|
||||
@ -5467,7 +5486,9 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
else if (TARGET_SPE_ABI && TARGET_SPE
|
||||
&& (SPE_VECTOR_MODE (mode)
|
||||
|| (TARGET_E500_DOUBLE && (mode == DFmode
|
||||
|| mode == DCmode))))
|
||||
|| mode == DCmode
|
||||
|| mode == TFmode
|
||||
|| mode == TCmode))))
|
||||
return rs6000_spe_function_arg (cum, mode, type);
|
||||
|
||||
else if (abi == ABI_V4)
|
||||
@ -9420,7 +9441,7 @@ rs6000_init_libfuncs (void)
|
||||
set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
|
||||
set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
|
||||
|
||||
if (TARGET_SOFT_FLOAT)
|
||||
if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
|
||||
{
|
||||
set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
|
||||
set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
|
||||
@ -11034,7 +11055,9 @@ print_operand (FILE *file, rtx x, int code)
|
||||
|
||||
/* Ugly hack because %y is overloaded. */
|
||||
if ((TARGET_SPE || TARGET_E500_DOUBLE)
|
||||
&& GET_MODE_SIZE (GET_MODE (x)) == 8)
|
||||
&& (GET_MODE_SIZE (GET_MODE (x)) == 8
|
||||
|| GET_MODE (x) == TFmode
|
||||
|| GET_MODE (x) == TImode))
|
||||
{
|
||||
/* Handle [reg]. */
|
||||
if (GET_CODE (tmp) == REG)
|
||||
@ -11366,6 +11389,14 @@ rs6000_generate_compare (enum rtx_code code)
|
||||
rs6000_compare_op1);
|
||||
break;
|
||||
|
||||
case TFmode:
|
||||
cmp = flag_unsafe_math_optimizations
|
||||
? gen_tsttfeq_gpr (compare_result, rs6000_compare_op0,
|
||||
rs6000_compare_op1)
|
||||
: gen_cmptfeq_gpr (compare_result, rs6000_compare_op0,
|
||||
rs6000_compare_op1);
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
@ -11390,6 +11421,14 @@ rs6000_generate_compare (enum rtx_code code)
|
||||
rs6000_compare_op1);
|
||||
break;
|
||||
|
||||
case TFmode:
|
||||
cmp = flag_unsafe_math_optimizations
|
||||
? gen_tsttfgt_gpr (compare_result, rs6000_compare_op0,
|
||||
rs6000_compare_op1)
|
||||
: gen_cmptfgt_gpr (compare_result, rs6000_compare_op0,
|
||||
rs6000_compare_op1);
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
@ -11414,6 +11453,14 @@ rs6000_generate_compare (enum rtx_code code)
|
||||
rs6000_compare_op1);
|
||||
break;
|
||||
|
||||
case TFmode:
|
||||
cmp = flag_unsafe_math_optimizations
|
||||
? gen_tsttflt_gpr (compare_result, rs6000_compare_op0,
|
||||
rs6000_compare_op1)
|
||||
: gen_cmptflt_gpr (compare_result, rs6000_compare_op0,
|
||||
rs6000_compare_op1);
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
@ -11457,6 +11504,14 @@ rs6000_generate_compare (enum rtx_code code)
|
||||
rs6000_compare_op1);
|
||||
break;
|
||||
|
||||
case TFmode:
|
||||
cmp = flag_unsafe_math_optimizations
|
||||
? gen_tsttfeq_gpr (compare_result2, rs6000_compare_op0,
|
||||
rs6000_compare_op1)
|
||||
: gen_cmptfeq_gpr (compare_result2, rs6000_compare_op0,
|
||||
rs6000_compare_op1);
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
@ -13504,7 +13559,7 @@ spe_func_has_64bit_regs_p (void)
|
||||
|
||||
if (SPE_VECTOR_MODE (mode))
|
||||
return true;
|
||||
if (TARGET_E500_DOUBLE && mode == DFmode)
|
||||
if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -20274,7 +20329,8 @@ rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
|
||||
&& ALTIVEC_VECTOR_MODE (mode))
|
||||
regno = ALTIVEC_ARG_RETURN;
|
||||
else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
|
||||
&& (mode == DFmode || mode == DCmode))
|
||||
&& (mode == DFmode || mode == DCmode
|
||||
|| mode == TFmode || mode == TCmode))
|
||||
return spe_build_register_parallel (mode, GP_ARG_RETURN);
|
||||
else
|
||||
regno = GP_ARG_RETURN;
|
||||
@ -20314,7 +20370,8 @@ rs6000_libcall_value (enum machine_mode mode)
|
||||
else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
|
||||
return rs6000_complex_function_value (mode);
|
||||
else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
|
||||
&& (mode == DFmode || mode == DCmode))
|
||||
&& (mode == DFmode || mode == DCmode
|
||||
|| mode == TFmode || mode == TCmode))
|
||||
return spe_build_register_parallel (mode, GP_ARG_RETURN);
|
||||
else
|
||||
regno = GP_ARG_RETURN;
|
||||
|
@ -1160,6 +1160,7 @@ enum reg_class
|
||||
&& reg_classes_intersect_p (FLOAT_REGS, CLASS)) \
|
||||
: (((TARGET_E500_DOUBLE \
|
||||
&& ((((TO) == DFmode) + ((FROM) == DFmode)) == 1 \
|
||||
|| (((TO) == TFmode) + ((FROM) == TFmode)) == 1 \
|
||||
|| (((TO) == DImode) + ((FROM) == DImode)) == 1)) \
|
||||
|| (TARGET_SPE \
|
||||
&& (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1)) \
|
||||
|
@ -176,7 +176,9 @@
|
||||
(define_mode_macro FP [(SF "TARGET_HARD_FLOAT")
|
||||
(DF "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)")
|
||||
(TF "!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")])
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
|
||||
&& TARGET_LONG_DOUBLE_128")])
|
||||
|
||||
; Various instructions that come in SI and DI forms.
|
||||
; A generic w/d attribute, for things like cmpw/cmpd.
|
||||
@ -5730,7 +5732,7 @@
|
||||
(clobber (match_dup 4))
|
||||
(clobber (match_dup 5))
|
||||
(clobber (match_dup 6))])]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS"
|
||||
"TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
|
||||
"
|
||||
{
|
||||
if (TARGET_E500_DOUBLE)
|
||||
@ -8538,7 +8540,7 @@
|
||||
[(set_attr "length" "8,8,8,20,20,16")])
|
||||
|
||||
(define_insn_and_split "*movtf_softfloat"
|
||||
[(set (match_operand:TF 0 "nonimmediate_operand" "=r,Y,r")
|
||||
[(set (match_operand:TF 0 "rs6000_nonimmediate_operand" "=r,Y,r")
|
||||
(match_operand:TF 1 "input_operand" "YGHF,r,r"))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& (TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_LONG_DOUBLE_128
|
||||
@ -8551,6 +8553,21 @@
|
||||
[(set_attr "length" "20,20,16")])
|
||||
|
||||
(define_expand "extenddftf2"
|
||||
[(set (match_operand:TF 0 "nonimmediate_operand" "")
|
||||
(float_extend:TF (match_operand:DF 1 "input_operand" "")))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
|
||||
&& TARGET_LONG_DOUBLE_128"
|
||||
{
|
||||
if (TARGET_E500_DOUBLE)
|
||||
emit_insn (gen_spe_extenddftf2 (operands[0], operands[1]));
|
||||
else
|
||||
emit_insn (gen_extenddftf2_fprs (operands[0], operands[1]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "extenddftf2_fprs"
|
||||
[(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
|
||||
(float_extend:TF (match_operand:DF 1 "input_operand" "")))
|
||||
(use (match_dup 2))])]
|
||||
@ -8586,7 +8603,9 @@
|
||||
[(set (match_operand:TF 0 "nonimmediate_operand" "")
|
||||
(float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
|
||||
&& TARGET_LONG_DOUBLE_128"
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (DFmode);
|
||||
emit_insn (gen_extendsfdf2 (tmp, operands[1]));
|
||||
@ -8598,7 +8617,9 @@
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "")
|
||||
(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
|
||||
&& TARGET_LONG_DOUBLE_128"
|
||||
"")
|
||||
|
||||
(define_insn_and_split "trunctfdf2_internal1"
|
||||
@ -8625,7 +8646,22 @@
|
||||
"fadd %0,%1,%L1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn_and_split "trunctfsf2"
|
||||
(define_expand "trunctfsf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "")
|
||||
(float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "")))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
|
||||
&& TARGET_LONG_DOUBLE_128"
|
||||
{
|
||||
if (TARGET_E500_DOUBLE)
|
||||
emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1]));
|
||||
else
|
||||
emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn_and_split "trunctfsf2_fprs"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
(float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))
|
||||
(clobber (match_scratch:DF 2 "=f"))]
|
||||
@ -8643,7 +8679,9 @@
|
||||
[(set (match_operand:TF 0 "gpc_reg_operand" "")
|
||||
(float:TF (match_operand:SI 1 "gpc_reg_operand" "")))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
|
||||
&& TARGET_LONG_DOUBLE_128"
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (DFmode);
|
||||
expand_float (tmp, operands[1], false);
|
||||
@ -8664,6 +8702,22 @@
|
||||
(set_attr "length" "20")])
|
||||
|
||||
(define_expand "fix_trunctfsi2"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
(fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& (TARGET_POWER2 || TARGET_POWERPC)
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
|
||||
&& TARGET_LONG_DOUBLE_128"
|
||||
{
|
||||
if (TARGET_E500_DOUBLE)
|
||||
emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1]));
|
||||
else
|
||||
emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "fix_trunctfsi2_fprs"
|
||||
[(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
(fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
|
||||
(clobber (match_dup 2))
|
||||
@ -8705,7 +8759,16 @@
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "negtf2"
|
||||
(define_expand "negtf2"
|
||||
[(set (match_operand:TF 0 "gpc_reg_operand" "")
|
||||
(neg:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
|
||||
&& TARGET_LONG_DOUBLE_128"
|
||||
"")
|
||||
|
||||
(define_insn "negtf2_internal"
|
||||
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
|
||||
(neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
|
||||
"!TARGET_IEEEQUAD
|
||||
@ -8721,14 +8784,24 @@
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_expand "abstf2"
|
||||
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
|
||||
(abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
|
||||
[(set (match_operand:TF 0 "gpc_reg_operand" "")
|
||||
(abs:TF (match_operand:TF 1 "gpc_reg_operand" "")))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
||||
&& TARGET_HARD_FLOAT
|
||||
&& (TARGET_FPRS || TARGET_E500_DOUBLE)
|
||||
&& TARGET_LONG_DOUBLE_128"
|
||||
"
|
||||
{
|
||||
rtx label = gen_label_rtx ();
|
||||
emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
|
||||
if (TARGET_E500_DOUBLE)
|
||||
{
|
||||
if (flag_unsafe_math_optimizations)
|
||||
emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label));
|
||||
else
|
||||
emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
|
||||
emit_label (label);
|
||||
DONE;
|
||||
}")
|
||||
@ -8761,7 +8834,7 @@
|
||||
; List r->r after r->"o<>", otherwise reload will try to reload a
|
||||
; non-offsettable address by using r->r which won't make progress.
|
||||
(define_insn "*movdi_internal32"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,r,r,*f,*f,m,r")
|
||||
[(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*f,*f,m,r")
|
||||
(match_operand:DI 1 "input_operand" "r,r,m,f,m,f,IJKnGHF"))]
|
||||
"! TARGET_POWERPC64
|
||||
&& (gpc_reg_operand (operands[0], DImode)
|
||||
@ -8798,7 +8871,7 @@
|
||||
}")
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "")
|
||||
[(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "")
|
||||
(match_operand:DI 1 "input_operand" ""))]
|
||||
"reload_completed && !TARGET_POWERPC64
|
||||
&& gpr_or_gpr_p (operands[0], operands[1])"
|
||||
|
@ -1,5 +1,6 @@
|
||||
;; e500 SPE description
|
||||
;; Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
|
||||
|
||||
;; This file is part of GCC.
|
||||
@ -29,12 +30,24 @@
|
||||
(TSTDFGT_GPR 1009)
|
||||
(CMPDFLT_GPR 1010)
|
||||
(TSTDFLT_GPR 1011)
|
||||
(E500_CR_IOR_COMPARE 1012)
|
||||
(CMPTFEQ_GPR 1012)
|
||||
(TSTTFEQ_GPR 1013)
|
||||
(CMPTFGT_GPR 1014)
|
||||
(TSTTFGT_GPR 1015)
|
||||
(CMPTFLT_GPR 1016)
|
||||
(TSTTFLT_GPR 1017)
|
||||
(E500_CR_IOR_COMPARE 1018)
|
||||
])
|
||||
|
||||
;; Modes using a 64-bit register.
|
||||
(define_mode_macro SPE64 [DF V4HI V2SF V1DI V2SI])
|
||||
|
||||
;; Likewise, but allow TFmode (two registers) as well.
|
||||
(define_mode_macro SPE64TF [DF V4HI V2SF V1DI V2SI TF])
|
||||
|
||||
;; DImode and TImode.
|
||||
(define_mode_macro DITI [DI TI])
|
||||
|
||||
(define_insn "*negsf2_gpr"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=r")
|
||||
(neg:SF (match_operand:SF 1 "gpc_reg_operand" "r")))]
|
||||
@ -2198,25 +2211,57 @@
|
||||
;; Double-precision floating point instructions.
|
||||
|
||||
;; FIXME: Add o=r option.
|
||||
(define_insn "*frob_df_di"
|
||||
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r")
|
||||
(subreg:DF (match_operand:DI 1 "input_operand" "r,m") 0))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
(define_insn "*frob_<SPE64:mode>_<DITI:mode>"
|
||||
[(set (match_operand:SPE64 0 "nonimmediate_operand" "=r,r")
|
||||
(subreg:SPE64 (match_operand:DITI 1 "input_operand" "r,m") 0))]
|
||||
"(TARGET_E500_DOUBLE && <SPE64:MODE>mode == DFmode)
|
||||
|| (TARGET_SPE && <SPE64:MODE>mode != DFmode)"
|
||||
"@
|
||||
evmergelo %0,%1,%L1
|
||||
evldd%X1 %0,%y1")
|
||||
|
||||
(define_insn "*frob_di_df"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=&r")
|
||||
(subreg:DI (match_operand:DF 1 "input_operand" "r") 0))]
|
||||
(define_insn "*frob_tf_ti"
|
||||
[(set (match_operand:TF 0 "gpc_reg_operand" "=r")
|
||||
(subreg:TF (match_operand:TI 1 "gpc_reg_operand" "r") 0))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"evmergelo %0,%1,%L1\;evmergelo %L0,%Y1,%Z1")
|
||||
|
||||
(define_insn "*frob_<mode>_di_2"
|
||||
[(set (subreg:DI (match_operand:SPE64TF 0 "nonimmediate_operand" "+&r,r") 0)
|
||||
(match_operand:DI 1 "input_operand" "r,m"))]
|
||||
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|
||||
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
|
||||
"@
|
||||
evmergelo %0,%1,%L1
|
||||
evldd%X1 %0,%y1")
|
||||
|
||||
(define_insn "*frob_tf_di_8_2"
|
||||
[(set (subreg:DI (match_operand:TF 0 "nonimmediate_operand" "+&r,r") 8)
|
||||
(match_operand:DI 1 "input_operand" "r,m"))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"@
|
||||
evmergelo %L0,%1,%L1
|
||||
evldd%X1 %L0,%y1")
|
||||
|
||||
(define_insn "*frob_di_<mode>"
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=&r")
|
||||
(subreg:DI (match_operand:SPE64TF 1 "input_operand" "r") 0))]
|
||||
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|
||||
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
|
||||
"evmergehi %0,%1,%1\;mr %L0,%1"
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
(define_insn "*frob_di_df_2"
|
||||
[(set (subreg:DF (match_operand:DI 0 "register_operand" "=&r,r") 0)
|
||||
(match_operand:DF 1 "input_operand" "r,m"))]
|
||||
(define_insn "*frob_ti_tf"
|
||||
[(set (match_operand:TI 0 "nonimmediate_operand" "=&r")
|
||||
(subreg:TI (match_operand:TF 1 "input_operand" "r") 0))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"evmergehi %0,%1,%1\;mr %L0,%1\;evmergehi %Y0,%L1,%L1\;mr %Z0,%L1")
|
||||
|
||||
(define_insn "*frob_<DITI:mode>_<SPE64:mode>_2"
|
||||
[(set (subreg:SPE64 (match_operand:DITI 0 "register_operand" "+&r,r") 0)
|
||||
(match_operand:SPE64 1 "input_operand" "r,m"))]
|
||||
"(TARGET_E500_DOUBLE && <SPE64:MODE>mode == DFmode)
|
||||
|| (TARGET_SPE && <SPE64:MODE>mode != DFmode)"
|
||||
"*
|
||||
{
|
||||
switch (which_alternative)
|
||||
@ -2244,10 +2289,43 @@
|
||||
}"
|
||||
[(set_attr "length" "8,8")])
|
||||
|
||||
; As the above, but TImode at offset 8.
|
||||
(define_insn "*frob_ti_<mode>_8_2"
|
||||
[(set (subreg:SPE64 (match_operand:TI 0 "register_operand" "+&r,r") 8)
|
||||
(match_operand:SPE64 1 "input_operand" "r,m"))]
|
||||
"(TARGET_E500_DOUBLE && <MODE>mode == DFmode)
|
||||
|| (TARGET_SPE && <MODE>mode != DFmode)"
|
||||
"*
|
||||
{
|
||||
switch (which_alternative)
|
||||
{
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
case 0:
|
||||
return \"evmergehi %Y0,%1,%1\;mr %Z0,%1\";
|
||||
case 1:
|
||||
if (!offsettable_nonstrict_memref_p (operands[1]))
|
||||
return \"evldd%X1 %Z0,%y1\;evmergehi %Y0,%Z0,%Z0\";
|
||||
if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
|
||||
operands[1], 0))
|
||||
return \"{l|lwz} %Z0,%L1\;{l|lwz} %Y0,%1\";
|
||||
else
|
||||
return \"{l%U1%X1|lwz%U1%X1} %Y0,%1\;{l|lwz} %Z0,%L1\";
|
||||
}
|
||||
}"
|
||||
[(set_attr "length" "8,8")])
|
||||
|
||||
(define_insn "*frob_ti_tf_2"
|
||||
[(set (subreg:TF (match_operand:TI 0 "gpc_reg_operand" "=&r") 0)
|
||||
(match_operand:TF 1 "gpc_reg_operand" "r"))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"evmergehi %0,%1,%1\;mr %L0,%1\;evmergehi %Y0,%L1,%L1\;mr %Z0,%L1")
|
||||
|
||||
(define_insn "*mov_si<mode>_e500_subreg0"
|
||||
[(set (subreg:SI (match_operand:SPE64 0 "register_operand" "+r,&r") 0)
|
||||
[(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,&r") 0)
|
||||
(match_operand:SI 1 "input_operand" "r,m"))]
|
||||
"(TARGET_E500_DOUBLE && <MODE>mode == DFmode) || (TARGET_SPE && <MODE>mode != DFmode)"
|
||||
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|
||||
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
|
||||
"@
|
||||
evmergelo %0,%1,%0
|
||||
evmergelohi %0,%0,%0\;{l%U1%X1|lwz%U1%X1} %0,%1\;evmergelohi %0,%0,%0")
|
||||
@ -2256,28 +2334,63 @@
|
||||
;; the offset.
|
||||
(define_insn "*mov_si<mode>_e500_subreg0_2"
|
||||
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
|
||||
(subreg:SI (match_operand:SPE64 1 "register_operand" "+r,&r") 0))]
|
||||
"(TARGET_E500_DOUBLE && <MODE>mode == DFmode) || (TARGET_SPE && <MODE>mode != DFmode)"
|
||||
(subreg:SI (match_operand:SPE64TF 1 "register_operand" "+r,&r") 0))]
|
||||
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|
||||
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
|
||||
"@
|
||||
evmergehi %0,%0,%1
|
||||
evmergelohi %1,%1,%1\;{st%U0%X0|stw%U0%X0} %1,%0")
|
||||
|
||||
(define_insn "*mov_si<mode>_e500_subreg4"
|
||||
[(set (subreg:SI (match_operand:SPE64 0 "register_operand" "+r,r") 4)
|
||||
[(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,r") 4)
|
||||
(match_operand:SI 1 "input_operand" "r,m"))]
|
||||
"(TARGET_E500_DOUBLE && <MODE>mode == DFmode) || (TARGET_SPE && <MODE>mode != DFmode)"
|
||||
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|
||||
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
|
||||
"@
|
||||
mr %0,%1
|
||||
{l%U1%X1|lwz%U1%X1} %0,%1")
|
||||
|
||||
(define_insn "*mov_si<mode>_e500_subreg4_2"
|
||||
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
|
||||
(subreg:SI (match_operand:SPE64 1 "register_operand" "r,r") 4))]
|
||||
"(TARGET_E500_DOUBLE && <MODE>mode == DFmode) || (TARGET_SPE && <MODE>mode != DFmode)"
|
||||
(subreg:SI (match_operand:SPE64TF 1 "register_operand" "r,r") 4))]
|
||||
"(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
|
||||
|| (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode)"
|
||||
"@
|
||||
mr %0,%1
|
||||
{st%U0%X0|stw%U0%X0} %1,%0")
|
||||
|
||||
(define_insn "*mov_sitf_e500_subreg8"
|
||||
[(set (subreg:SI (match_operand:TF 0 "register_operand" "+r,&r") 8)
|
||||
(match_operand:SI 1 "input_operand" "r,m"))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"@
|
||||
evmergelo %L0,%1,%L0
|
||||
evmergelohi %L0,%L0,%L0\;{l%U1%X1|lwz%U1%X1} %L0,%1\;evmergelohi %L0,%L0,%L0")
|
||||
|
||||
(define_insn "*mov_sitf_e500_subreg8_2"
|
||||
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
|
||||
(subreg:SI (match_operand:TF 1 "register_operand" "+r,&r") 8))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"@
|
||||
evmergehi %0,%0,%L1
|
||||
evmergelohi %L1,%L1,%L1\;{st%U0%X0|stw%U0%X0} %L1,%0")
|
||||
|
||||
(define_insn "*mov_sitf_e500_subreg12"
|
||||
[(set (subreg:SI (match_operand:TF 0 "register_operand" "+r,r") 12)
|
||||
(match_operand:SI 1 "input_operand" "r,m"))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"@
|
||||
mr %L0,%1
|
||||
{l%U1%X1|lwz%U1%X1} %L0,%1")
|
||||
|
||||
(define_insn "*mov_sitf_e500_subreg12_2"
|
||||
[(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
|
||||
(subreg:SI (match_operand:TF 1 "register_operand" "r,r") 12))]
|
||||
"TARGET_E500_DOUBLE"
|
||||
"@
|
||||
mr %0,%L1
|
||||
{st%U0%X0|stw%U0%X0} %L1,%0")
|
||||
|
||||
;; FIXME: Allow r=CONST0.
|
||||
(define_insn "*movdf_e500_double"
|
||||
[(set (match_operand:DF 0 "rs6000_nonimmediate_operand" "=r,r,m")
|
||||
@ -2354,6 +2467,133 @@
|
||||
"TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
|
||||
"efddiv %0,%1,%2")
|
||||
|
||||
;; Double-precision floating point instructions for IBM long double.
|
||||
|
||||
(define_insn_and_split "spe_trunctfdf2_internal1"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=r,?r")
|
||||
(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,r")))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
|
||||
"@
|
||||
#
|
||||
evor %0,%1,%1"
|
||||
"&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
|
||||
[(const_int 0)]
|
||||
{
|
||||
emit_note (NOTE_INSN_DELETED);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn_and_split "spe_trunctfsf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=r")
|
||||
(float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "r")))
|
||||
(clobber (match_scratch:DF 2 "=r"))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 2)
|
||||
(float_truncate:DF (match_dup 1)))
|
||||
(set (match_dup 0)
|
||||
(float_truncate:SF (match_dup 2)))]
|
||||
"")
|
||||
|
||||
(define_insn "spe_extenddftf2"
|
||||
[(set (match_operand:TF 0 "rs6000_nonimmediate_operand" "=r,?r,r,o")
|
||||
(float_extend:TF (match_operand:DF 1 "input_operand" "0,r,m,r")))
|
||||
(clobber (match_scratch:DF 2 "=X,X,X,&r"))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
|
||||
"@
|
||||
evxor %L0,%L0,%L0
|
||||
evor %0,%1,%1\;evxor %L0,%L0,%L0
|
||||
evldd%X1 %0,%y1\;evxor %L0,%L0,%L0
|
||||
evstdd%X0 %1,%y0\;evxor %2,%2,%2\;evstdd %2,%Y0")
|
||||
|
||||
(define_expand "spe_fix_trunctfsi2"
|
||||
[(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
(fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
|
||||
(clobber (match_dup 2))
|
||||
(clobber (match_dup 3))
|
||||
(clobber (match_dup 4))])]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
|
||||
{
|
||||
operands[2] = gen_reg_rtx (DFmode);
|
||||
operands[3] = gen_reg_rtx (SImode);
|
||||
operands[4] = gen_reg_rtx (SImode);
|
||||
})
|
||||
|
||||
; Like fix_trunc_helper, add with rounding towards 0.
|
||||
(define_insn "spe_fix_trunctfsi2_internal"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
||||
(fix:SI (match_operand:TF 1 "gpc_reg_operand" "r")))
|
||||
(clobber (match_operand:DF 2 "gpc_reg_operand" "=r"))
|
||||
(clobber (match_operand:SI 3 "gpc_reg_operand" "=&r"))
|
||||
(clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
|
||||
"mfspefscr %3\;rlwinm %4,%3,0,0,29\;ori %4,%4,1\;efdadd %2,%1,%L1\;mtspefscr %3\;efdctsiz %0, %2")
|
||||
|
||||
(define_insn "spe_negtf2_internal"
|
||||
[(set (match_operand:TF 0 "gpc_reg_operand" "=r")
|
||||
(neg:TF (match_operand:TF 1 "gpc_reg_operand" "r")))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
|
||||
"*
|
||||
{
|
||||
if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
|
||||
return \"efdneg %L0,%L1\;efdneg %0,%1\";
|
||||
else
|
||||
return \"efdneg %0,%1\;efdneg %L0,%L1\";
|
||||
}")
|
||||
|
||||
(define_expand "spe_abstf2_cmp"
|
||||
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
|
||||
(match_operand:TF 1 "gpc_reg_operand" "f"))
|
||||
(set (match_dup 3) (match_dup 5))
|
||||
(set (match_dup 5) (abs:DF (match_dup 5)))
|
||||
(set (match_dup 4) (unspec:CCFP [(compare:CCFP (match_dup 3)
|
||||
(match_dup 5))] CMPDFEQ_GPR))
|
||||
(set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
|
||||
(label_ref (match_operand 2 "" ""))
|
||||
(pc)))
|
||||
(set (match_dup 6) (neg:DF (match_dup 6)))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
|
||||
"
|
||||
{
|
||||
const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
|
||||
const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
|
||||
operands[3] = gen_reg_rtx (DFmode);
|
||||
operands[4] = gen_reg_rtx (CCFPmode);
|
||||
operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
|
||||
operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
|
||||
}")
|
||||
|
||||
(define_expand "spe_abstf2_tst"
|
||||
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
|
||||
(match_operand:TF 1 "gpc_reg_operand" "f"))
|
||||
(set (match_dup 3) (match_dup 5))
|
||||
(set (match_dup 5) (abs:DF (match_dup 5)))
|
||||
(set (match_dup 4) (unspec:CCFP [(compare:CCFP (match_dup 3)
|
||||
(match_dup 5))] TSTDFEQ_GPR))
|
||||
(set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
|
||||
(label_ref (match_operand 2 "" ""))
|
||||
(pc)))
|
||||
(set (match_dup 6) (neg:DF (match_dup 6)))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128"
|
||||
"
|
||||
{
|
||||
const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
|
||||
const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
|
||||
operands[3] = gen_reg_rtx (DFmode);
|
||||
operands[4] = gen_reg_rtx (CCFPmode);
|
||||
operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
|
||||
operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
|
||||
}")
|
||||
|
||||
;; Vector move instructions.
|
||||
|
||||
(define_expand "movv2si"
|
||||
@ -2803,6 +3043,80 @@
|
||||
"efdtstlt %0,%1,%2"
|
||||
[(set_attr "type" "veccmpsimple")])
|
||||
|
||||
;; Same thing, but for IBM long double.
|
||||
|
||||
(define_insn "cmptfeq_gpr"
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
(unspec:CCFP
|
||||
[(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
|
||||
(match_operand:TF 2 "gpc_reg_operand" "r"))]
|
||||
CMPTFEQ_GPR))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
|
||||
&& !flag_unsafe_math_optimizations"
|
||||
"efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmpeq %0,%L1,%L2"
|
||||
[(set_attr "type" "veccmp")])
|
||||
|
||||
(define_insn "tsttfeq_gpr"
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
(unspec:CCFP
|
||||
[(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
|
||||
(match_operand:TF 2 "gpc_reg_operand" "r"))]
|
||||
TSTTFEQ_GPR))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
|
||||
&& flag_unsafe_math_optimizations"
|
||||
"efdtsteq %0,%1,%2\;bng %0,$+8\;efdtsteq %0,%L1,%L2"
|
||||
[(set_attr "type" "veccmpsimple")])
|
||||
|
||||
(define_insn "cmptfgt_gpr"
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
(unspec:CCFP
|
||||
[(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
|
||||
(match_operand:TF 2 "gpc_reg_operand" "r"))]
|
||||
CMPTFGT_GPR))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
|
||||
&& !flag_unsafe_math_optimizations"
|
||||
"efdcmpgt %0,%1,%2\;bgt %0,$+16\;efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmpgt %0,%L1,%L2"
|
||||
[(set_attr "type" "veccmp")])
|
||||
|
||||
(define_insn "tsttfgt_gpr"
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
(unspec:CCFP
|
||||
[(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
|
||||
(match_operand:TF 2 "gpc_reg_operand" "r"))]
|
||||
TSTTFGT_GPR))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
|
||||
&& flag_unsafe_math_optimizations"
|
||||
"efdtstgt %0,%1,%2\;bgt %0,$+16\;efdtsteq %0,%1,%2\;bng %0,$+8\;efdtstgt %0,%L1,%L2"
|
||||
[(set_attr "type" "veccmpsimple")])
|
||||
|
||||
(define_insn "cmptflt_gpr"
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
(unspec:CCFP
|
||||
[(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
|
||||
(match_operand:TF 2 "gpc_reg_operand" "r"))]
|
||||
CMPTFLT_GPR))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
|
||||
&& !flag_unsafe_math_optimizations"
|
||||
"efdcmplt %0,%1,%2\;bgt %0,$+16\;efdcmpeq %0,%1,%2\;bng %0,$+8\;efdcmplt %0,%L1,%L2"
|
||||
[(set_attr "type" "veccmp")])
|
||||
|
||||
(define_insn "tsttflt_gpr"
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
(unspec:CCFP
|
||||
[(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "r")
|
||||
(match_operand:TF 2 "gpc_reg_operand" "r"))]
|
||||
TSTTFLT_GPR))]
|
||||
"!TARGET_IEEEQUAD
|
||||
&& TARGET_HARD_FLOAT && TARGET_E500_DOUBLE && TARGET_LONG_DOUBLE_128
|
||||
&& flag_unsafe_math_optimizations"
|
||||
"efdtstlt %0,%1,%2\;bgt %0,$+16\;efdtsteq %0,%1,%2\;bng %0,$+8\;efdtstlt %0,%L1,%L2"
|
||||
[(set_attr "type" "veccmpsimple")])
|
||||
|
||||
;; Like cceq_ior_compare, but compare the GT bits.
|
||||
(define_insn "e500_cr_ior_compare"
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
|
@ -1,3 +1,7 @@
|
||||
2007-01-23 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* config/rs6000/t-ldbl128: Always use -mlong-double-128.
|
||||
|
||||
2007-01-21 Andrew Pinski <pinskia@gmail.com>
|
||||
|
||||
PR target/30519
|
||||
|
@ -1,7 +1,3 @@
|
||||
SHLIB_MAPFILES += $(gcc_srcdir)/config/rs6000/libgcc-ppc-glibc.ver
|
||||
|
||||
# Use -mlong-double-128 only when not compiling nof libgcc.
|
||||
predefined-macros := $(shell true | $(CC) $(CFLAGS) -x c -dD -E -)
|
||||
ifeq ($(findstring _SOFT_FLOAT,$(predefined-macros)),)
|
||||
HOST_LIBGCC2_CFLAGS += -mlong-double-128
|
||||
endif
|
||||
|
Loading…
Reference in New Issue
Block a user