Improve floating point conversions on powerpc
From-SVN: r163598
This commit is contained in:
parent
a3c85b7499
commit
7042fe5ef8
120
gcc/ChangeLog
120
gcc/ChangeLog
|
@ -1,3 +1,123 @@
|
|||
2010-08-23 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
* config/rs6000/rs6000-protos.h (rs6000_address_for_fpconvert):
|
||||
New declaration.
|
||||
(rs6000_allocate_stack_temp): Ditto.
|
||||
(rs6000_expand_convert_si_to_sfdf): Ditto.
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_override_options): Adjust long
|
||||
line. Update the options set if power6 or power7 server/embedded
|
||||
type options are used. If we give a warning for no vsx under
|
||||
-mcpu=power7 -mno-altivec, mark -mvsx as an explicit option.
|
||||
(rs6000_allocate_stack_temp): New function to allocate a stack
|
||||
tempoary and adjust the address so it meets either REG+OFFSET or
|
||||
REG+REG addressing requirements.
|
||||
(rs6000_address_for_fpconvert): Adjust REG+OFFSET addresses so
|
||||
that they can be used with the LFIWAX/LFIWZX instrucitons.
|
||||
(rs6000_expand_convert_si_to_sfdf): New helper funciton for
|
||||
converting signed/unsigned SImode to either SFmode/DFmode.
|
||||
|
||||
* config/rs6000/rs6000.h (TARGET_FCFID): New macros to determine
|
||||
whether certain instructions can be generated.
|
||||
(TARGET_FCTIDZ): Ditto.
|
||||
(TARGET_STFIWX): Ditto.
|
||||
(TARGET_LFIWAX): Ditto.
|
||||
(TARGET_LFIWZX): Ditto.
|
||||
(TARGET_FCFIDS): Ditto.
|
||||
(TARGET_FCFIDU): Ditto.
|
||||
(TARGET_FCFIDUS): Ditto.
|
||||
(TARGET_FCTIDUZ): Ditto.
|
||||
(TARGET_FCTIWUZ): Ditto.
|
||||
|
||||
* config/rs6000/rs6000.md (UNSPEC_FCTIW): New unspec constants.
|
||||
(UNSPEC_FCTID): Ditto.
|
||||
(UNSPEC_LFIWAX): Ditto.
|
||||
(UNSPEC_LFIWZX): Ditto.
|
||||
(UNSPEC_FCTIWUZ): Ditto.
|
||||
(rreg): Use correct constraints.
|
||||
(SI_CONVERT_FP): New mode attribute for floating point conversion
|
||||
tests.
|
||||
(E500_CONVERT): Ditto.
|
||||
(lfiwax): New insns for converting from integer to floating point
|
||||
utilizing newer instructions. Attempt to optimize conversions
|
||||
that come from memory so that we don't load the value into a GPR,
|
||||
spill it to the stack and reload it into a FPR.
|
||||
(floatsi<mode>2_lfiwax): Ditto.
|
||||
(floatsi<mode>2_lfiwax_mem): Ditto.
|
||||
(floatsi<mode>2_lfiwax_mem2): Ditto.
|
||||
(lfiwzx): Ditto.
|
||||
(floatunssi<mode>2_lfiwzx): Ditto.
|
||||
(floatunssi<mode>2_lfiwzx_mem): Ditto.
|
||||
(floatunssi<mode>2_lfiwzx_mem2): Ditto.
|
||||
(floatdidf2_mem): Ditto.
|
||||
(floatunsdidf2_fcfidu): Ditto.
|
||||
(floatunsdidf2_mem): Ditto.
|
||||
(floatunsdisf2): Ditto.
|
||||
(floatunsdisf2_fcfidus): Ditto.
|
||||
(floatunsdisf2_mem): Ditto.
|
||||
(floatsidf2): Add support for LFIWAX/LFIWZX/FCFIDS/FCFIDU/FCFIDUS.
|
||||
Use FCFID on 32-bit hosts that support it.
|
||||
(floatsidf2_internal): Ditto.
|
||||
(floatunssisf2): Ditto.
|
||||
(floatunssidf2): Ditto.
|
||||
(floatunssidf2_internal): Ditto.
|
||||
(floatsisf2): Ditto.
|
||||
(floatdidf2): Ditto.
|
||||
(floatdidf2_fpr): Ditto.
|
||||
(floatunsdidf2): Ditto.
|
||||
(floatdisf2): Ditto.
|
||||
(floatdisf2_fcfids): Ditto.
|
||||
(floatdisf2_internal1): Ditto.
|
||||
(fixuns_truncsfsi2): Delete, merge into common pattern for both
|
||||
SF/DF. Add power7 support.
|
||||
(fix_truncsfsi2): Ditto.
|
||||
(fixuns_truncdfsi2): Ditto.
|
||||
(fixuns_truncdfdi2): Ditto.
|
||||
(fix_truncdfsi2): Ditto.
|
||||
(fix_truncdfsi2_internal): Ditto.
|
||||
(fix_truncdfsi2_internal_gfxopt): Ditto.
|
||||
(fix_truncdfsi2_mfpgpr): Ditto.
|
||||
(fctiwz): Ditto.
|
||||
(btruncdf2): Ditto.
|
||||
(btruncdf2_fpr): Ditto.
|
||||
(btructsf2): Ditto.
|
||||
(ceildf2): Ditto.
|
||||
(ceildf2_fpr): Ditto.
|
||||
(ceilsf2): Ditto.
|
||||
(floordf2): Ditto.
|
||||
(floordf2_fpr): Ditto.
|
||||
(floorsf2): Ditto.
|
||||
(rounddf2): Ditto.
|
||||
(rounddf2_fpr): Ditto.
|
||||
(roundsf2): Ditto.
|
||||
(fix_trunc<mode>si2): Combine SF/DF conversion into one insn.
|
||||
(fix_trunc<mode>di2): Ditto.
|
||||
(fixuns_trunc<mode>si2): Ditto.
|
||||
(fixuns_trunc<mode>di2): Ditto.
|
||||
(fctiwz_<mode>): Ditto.
|
||||
(btrunc<mode>2): Ditto.
|
||||
(btrunc<mode>2_fpr): Ditto.
|
||||
(ceil<mode>2): Ditto.
|
||||
(ceil<mode>2_fpr): Ditto.
|
||||
(floor<mode>2): Ditto.
|
||||
(float<mode>2_fpr): Ditto.
|
||||
(round<mode>2): Ditto.
|
||||
(round<mode>2_fpr): Ditto.
|
||||
(fix_trunc<mode>si2_stfiwx): New insn for machines with STFIWX.
|
||||
(fixuns_trunc<mode>si2_stfiwx): Ditto.
|
||||
(fix_truncdfsi2_internal): Ditto.
|
||||
(fix_trunc<mode>si2_mem): Combiner pattern to eliminate storing
|
||||
converted value on stack, loaded into GPR, and then stored into
|
||||
the final destination.
|
||||
(fix_trunc<mode>di2_fctidz): New pattern for targets supporting
|
||||
FCTIDZ.
|
||||
(lrint<mode>di2): New insn, provide the lrint builtin functions.
|
||||
(ftruncdf2): Delete, unused.
|
||||
(fix_trunctfsi2_internal): Use gen_fctiwz_df, not gen_fctiwz.
|
||||
|
||||
* config/rs6000/vsx.md (toplevel): Update copyright year.
|
||||
(VSr2): Use "ws" contraint for DFmode, not "!r#r".
|
||||
(VSr3): Ditto.
|
||||
|
||||
2010-08-27 Basile Starynkevitch <basile@starynkevitch.net>
|
||||
Jeremie Salvucci <jeremie.salvucci@free.fr>
|
||||
|
|
|
@ -129,6 +129,9 @@ extern void rs6000_emit_parity (rtx, rtx);
|
|||
|
||||
extern rtx rs6000_machopic_legitimize_pic_address (rtx, enum machine_mode,
|
||||
rtx);
|
||||
extern rtx rs6000_address_for_fpconvert (rtx);
|
||||
extern rtx rs6000_allocate_stack_temp (enum machine_mode, bool, bool);
|
||||
extern void rs6000_expand_convert_si_to_sfdf (rtx, rtx, bool);
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
#ifdef TREE_CODE
|
||||
|
|
|
@ -2510,10 +2510,10 @@ rs6000_override_options (const char *default_cpu)
|
|||
POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
|
||||
| MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
|
||||
| MASK_MFPGPR | MASK_RECIP_PRECISION},
|
||||
{"power7", PROCESSOR_POWER7,
|
||||
{"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
|
||||
POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
|
||||
| MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
|
||||
| MASK_VSX| MASK_RECIP_PRECISION}, /* Don't add MASK_ISEL by default */
|
||||
| MASK_VSX | MASK_RECIP_PRECISION},
|
||||
{"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
|
||||
{"powerpc64", PROCESSOR_POWERPC64,
|
||||
POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
|
||||
|
@ -2550,15 +2550,19 @@ rs6000_override_options (const char *default_cpu)
|
|||
ISA_2_1_MASKS = MASK_MFCRF,
|
||||
ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
|
||||
|
||||
/* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and
|
||||
don't add ALTIVEC, since in general it isn't a win on power6. */
|
||||
ISA_2_5_MASKS = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
|
||||
| MASK_DFP),
|
||||
/* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't
|
||||
add ALTIVEC, since in general it isn't a win on power6. In ISA 2.04,
|
||||
fsel, fre, fsqrt, etc. were no longer documented as optional. Group
|
||||
masks by server and embedded. */
|
||||
ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
|
||||
| MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
|
||||
ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
|
||||
|
||||
/* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
|
||||
altivec is a win so enable it. */
|
||||
ISA_2_6_MASKS = (ISA_2_5_MASKS | MASK_ALTIVEC | MASK_POPCNTD
|
||||
| MASK_VSX | MASK_RECIP_PRECISION)
|
||||
ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
|
||||
ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
|
||||
| MASK_VSX)
|
||||
};
|
||||
|
||||
/* Numerous experiment shows that IRA based loop pressure
|
||||
|
@ -2699,15 +2703,22 @@ rs6000_override_options (const char *default_cpu)
|
|||
{
|
||||
warning (0, msg);
|
||||
target_flags &= ~ MASK_VSX;
|
||||
target_flags_explicit |= MASK_VSX;
|
||||
}
|
||||
}
|
||||
|
||||
/* For the newer switches (vsx, dfp, etc.) set some of the older options,
|
||||
unless the user explicitly used the -mno-<option> to disable the code. */
|
||||
if (TARGET_VSX)
|
||||
target_flags |= (ISA_2_6_MASKS & ~target_flags_explicit);
|
||||
target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
|
||||
else if (TARGET_POPCNTD)
|
||||
target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
|
||||
else if (TARGET_DFP)
|
||||
target_flags |= (ISA_2_5_MASKS & ~target_flags_explicit);
|
||||
target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
|
||||
else if (TARGET_CMPB)
|
||||
target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
|
||||
else if (TARGET_POPCNTB || TARGET_FPRND)
|
||||
target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
|
||||
else if (TARGET_ALTIVEC)
|
||||
target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
|
||||
|
||||
|
@ -26959,4 +26970,122 @@ rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a stack temp and fixup the address so it meets the particular
|
||||
memory requirements (either offetable or REG+REG addressing). */
|
||||
|
||||
rtx
|
||||
rs6000_allocate_stack_temp (enum machine_mode mode,
|
||||
bool offsettable_p,
|
||||
bool reg_reg_p)
|
||||
{
|
||||
rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
|
||||
rtx addr = XEXP (stack, 0);
|
||||
int strict_p = (reload_in_progress || reload_completed);
|
||||
|
||||
if (!legitimate_indirect_address_p (addr, strict_p))
|
||||
{
|
||||
if (offsettable_p
|
||||
&& !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
|
||||
stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
|
||||
|
||||
else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
|
||||
stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
/* Given a memory reference, if it is not a reg or reg+reg addressing, convert
|
||||
to such a form to deal with memory reference instructions like STFIWX that
|
||||
only take reg+reg addressing. */
|
||||
|
||||
rtx
|
||||
rs6000_address_for_fpconvert (rtx x)
|
||||
{
|
||||
int strict_p = (reload_in_progress || reload_completed);
|
||||
rtx addr;
|
||||
|
||||
gcc_assert (MEM_P (x));
|
||||
addr = XEXP (x, 0);
|
||||
if (! legitimate_indirect_address_p (addr, strict_p)
|
||||
&& ! legitimate_indexed_address_p (addr, strict_p))
|
||||
x = replace_equiv_address (x, copy_addr_to_reg (addr));
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Expand 32-bit int -> floating point conversions. Return true if
|
||||
successful. */
|
||||
|
||||
void
|
||||
rs6000_expand_convert_si_to_sfdf (rtx dest, rtx src, bool unsigned_p)
|
||||
{
|
||||
enum machine_mode dmode = GET_MODE (dest);
|
||||
rtx (*func_si) (rtx, rtx, rtx, rtx);
|
||||
rtx (*func_si_mem) (rtx, rtx);
|
||||
rtx (*func_di) (rtx, rtx);
|
||||
rtx reg, stack;
|
||||
|
||||
gcc_assert (GET_MODE (src) == SImode);
|
||||
|
||||
if (dmode == SFmode)
|
||||
{
|
||||
if (unsigned_p)
|
||||
{
|
||||
gcc_assert (TARGET_FCFIDUS && TARGET_LFIWZX);
|
||||
func_si = gen_floatunssisf2_lfiwzx;
|
||||
func_si_mem = gen_floatunssisf2_lfiwzx_mem;
|
||||
func_di = gen_floatunsdisf2;
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (TARGET_FCFIDS && TARGET_LFIWAX);
|
||||
func_si = gen_floatsisf2_lfiwax;
|
||||
func_si_mem = gen_floatsisf2_lfiwax_mem;
|
||||
func_di = gen_floatdisf2;
|
||||
}
|
||||
}
|
||||
|
||||
else if (dmode == DFmode)
|
||||
{
|
||||
if (unsigned_p)
|
||||
{
|
||||
gcc_assert (TARGET_FCFIDU && TARGET_LFIWZX);
|
||||
func_si = gen_floatunssidf2_lfiwzx;
|
||||
func_si_mem = gen_floatunssidf2_lfiwzx_mem;
|
||||
func_di = gen_floatunsdidf2;
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (TARGET_FCFID && TARGET_LFIWAX);
|
||||
func_si = gen_floatsidf2_lfiwax;
|
||||
func_si_mem = gen_floatsidf2_lfiwax_mem;
|
||||
func_di = gen_floatdidf2;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
if (MEM_P (src))
|
||||
{
|
||||
src = rs6000_address_for_fpconvert (src);
|
||||
emit_insn (func_si_mem (dest, src));
|
||||
}
|
||||
else if (!TARGET_MFPGPR)
|
||||
{
|
||||
reg = gen_reg_rtx (DImode);
|
||||
stack = rs6000_allocate_stack_temp (SImode, false, true);
|
||||
emit_insn (func_si (dest, src, stack, reg));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!REG_P (src))
|
||||
src = force_reg (SImode, src);
|
||||
reg = convert_to_mode (DImode, src, unsigned_p);
|
||||
emit_insn (func_di (dest, reg));
|
||||
}
|
||||
}
|
||||
|
||||
#include "gt-rs6000.h"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* Definitions of target machine for GNU compiler, for IBM RS/6000.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||
2010
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
|
||||
|
||||
|
@ -554,6 +555,25 @@ extern int rs6000_vector_align[];
|
|||
#define TARGET_E500_DOUBLE 0
|
||||
#define CHECK_E500_OPTIONS do { } while (0)
|
||||
|
||||
/* ISA 2.01 allowed FCFID to be done in 32-bit, previously it was 64-bit only.
|
||||
Enable 32-bit fcfid's on any of the switches for newer ISA machines or
|
||||
XILINX. */
|
||||
#define TARGET_FCFID (TARGET_POWERPC64 \
|
||||
|| TARGET_POPCNTB /* ISA 2.02 */ \
|
||||
|| TARGET_CMPB /* ISA 2.05 */ \
|
||||
|| TARGET_POPCNTD /* ISA 2.06 */ \
|
||||
|| TARGET_XILINX_FPU)
|
||||
|
||||
#define TARGET_FCTIDZ TARGET_FCFID
|
||||
#define TARGET_STFIWX TARGET_PPC_GFXOPT
|
||||
#define TARGET_LFIWAX TARGET_CMPB
|
||||
#define TARGET_LFIWZX TARGET_POPCNTD
|
||||
#define TARGET_FCFIDS TARGET_POPCNTD
|
||||
#define TARGET_FCFIDU TARGET_POPCNTD
|
||||
#define TARGET_FCFIDUS TARGET_POPCNTD
|
||||
#define TARGET_FCTIDUZ TARGET_POPCNTD
|
||||
#define TARGET_FCTIWUZ TARGET_POPCNTD
|
||||
|
||||
/* E500 processors only support plain "sync", not lwsync. */
|
||||
#define TARGET_NO_LWSYNC TARGET_E500
|
||||
|
||||
|
|
|
@ -105,6 +105,11 @@
|
|||
(UNSPEC_BPERM 51)
|
||||
(UNSPEC_COPYSIGN 52)
|
||||
(UNSPEC_PARITY 53)
|
||||
(UNSPEC_FCTIW 54)
|
||||
(UNSPEC_FCTID 55)
|
||||
(UNSPEC_LFIWAX 56)
|
||||
(UNSPEC_LFIWZX 57)
|
||||
(UNSPEC_FCTIWUZ 58)
|
||||
])
|
||||
|
||||
;;
|
||||
|
@ -252,13 +257,19 @@
|
|||
(DI "di")])
|
||||
|
||||
(define_mode_attr rreg [(SF "f")
|
||||
(DF "Ws")
|
||||
(V4SF "Wf")
|
||||
(V2DF "Wd")])
|
||||
(DF "ws")
|
||||
(V4SF "wf")
|
||||
(V2DF "wd")])
|
||||
|
||||
(define_mode_attr rreg2 [(SF "f")
|
||||
(DF "d")])
|
||||
|
||||
(define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
|
||||
(DF "TARGET_FCFID")])
|
||||
|
||||
(define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
|
||||
(DF "TARGET_E500_DOUBLE")])
|
||||
|
||||
(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
|
||||
(DF "TARGET_DOUBLE_FLOAT")])
|
||||
|
||||
|
@ -6424,29 +6435,149 @@
|
|||
|
||||
;; Conversions to and from floating-point.
|
||||
|
||||
(define_expand "fixuns_truncsfsi2"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
(unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
|
||||
"")
|
||||
; We don't define lfiwax/lfiwzx with the normal definition, because we
|
||||
; don't want to support putting SImode in FPR registers.
|
||||
(define_insn "lfiwax"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
|
||||
(unspec:DI [(match_operand:SI 1 "indexed_or_indirect_operand" "Z")]
|
||||
UNSPEC_LFIWAX))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
|
||||
"lfiwax %0,%y1"
|
||||
[(set_attr "type" "fpload")])
|
||||
|
||||
(define_expand "fix_truncsfsi2"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
(fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
|
||||
"")
|
||||
(define_insn_and_split "floatsi<mode>2_lfiwax"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>,<rreg2>")
|
||||
(float:SFDF (match_operand:SI 1 "nonimmediate_operand" "Z,r")))
|
||||
(clobber (match_operand:SI 2 "indexed_or_indirect_operand" "=Z,Z"))
|
||||
(clobber (match_operand:DI 3 "gpc_reg_operand" "=d,d"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
|
||||
&& <SI_CONVERT_FP>"
|
||||
"#"
|
||||
"MEM_P (operands[1]) || reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
if (MEM_P (operands[1]))
|
||||
{
|
||||
operands[1] = rs6000_address_for_fpconvert (operands[1]);
|
||||
emit_insn (gen_lfiwax (operands[3], operands[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_move_insn (operands[2], operands[1]);
|
||||
emit_insn (gen_lfiwax (operands[3], operands[2]));
|
||||
}
|
||||
emit_insn (gen_floatdi<mode>2 (operands[0], operands[3]));
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "8,12")])
|
||||
|
||||
(define_expand "fixuns_truncdfsi2"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
(unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
|
||||
"")
|
||||
(define_insn_and_split "floatsi<mode>2_lfiwax_mem"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
|
||||
(float:SFDF (match_operand:SI 1 "memory_operand" "Z")))
|
||||
(clobber (match_scratch:DI 2 "=d"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
|
||||
&& <SI_CONVERT_FP>"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
emit_insn (gen_lfiwax (operands[2], operands[1]));
|
||||
emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
(define_expand "fixuns_truncdfdi2"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
|
||||
"TARGET_HARD_FLOAT && TARGET_VSX"
|
||||
"")
|
||||
(define_insn_and_split "floatsi<mode>2_lfiwax_mem2"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
|
||||
(float:SFDF
|
||||
(sign_extend:DI
|
||||
(match_operand:SI 1 "memory_operand" "Z"))))
|
||||
(clobber (match_scratch:DI 2 "=d"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
|
||||
&& <SI_CONVERT_FP>"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
emit_insn (gen_lfiwax (operands[2], operands[1]));
|
||||
emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
(define_insn "lfiwzx"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
|
||||
(unspec:DI [(match_operand:SI 1 "indexed_or_indirect_operand" "Z")]
|
||||
UNSPEC_LFIWZX))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
|
||||
"lfiwzx %0,%y1"
|
||||
[(set_attr "type" "fpload")])
|
||||
|
||||
(define_insn_and_split "floatunssi<mode>2_lfiwzx"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>,<rreg2>")
|
||||
(unsigned_float:SFDF (match_operand:SI 1 "gpc_reg_operand" "Z,r")))
|
||||
(clobber (match_operand:SI 2 "indexed_or_indirect_operand" "=Z,Z"))
|
||||
(clobber (match_operand:DI 3 "gpc_reg_operand" "=d,d"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
|
||||
&& <SI_CONVERT_FP>"
|
||||
"#"
|
||||
"MEM_P (operands[1]) || reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
if (MEM_P (operands[1]))
|
||||
{
|
||||
operands[1] = rs6000_address_for_fpconvert (operands[1]);
|
||||
emit_insn (gen_lfiwzx (operands[3], operands[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_move_insn (operands[2], operands[1]);
|
||||
emit_insn (gen_lfiwzx (operands[3], operands[2]));
|
||||
}
|
||||
emit_insn (gen_floatdi<mode>2 (operands[0], operands[3]));
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "8,12")])
|
||||
|
||||
(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
|
||||
(unsigned_float:SFDF (match_operand:SI 1 "memory_operand" "Z")))
|
||||
(clobber (match_scratch:DI 2 "=d"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
|
||||
&& <SI_CONVERT_FP>"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
emit_insn (gen_lfiwzx (operands[2], operands[1]));
|
||||
emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem2"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
|
||||
(unsigned_float:SFDF
|
||||
(zero_extend:DI
|
||||
(match_operand:SI 1 "memory_operand" "Z"))))
|
||||
(clobber (match_scratch:DI 2 "=d"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
|
||||
&& <SI_CONVERT_FP>"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
emit_insn (gen_lfiwzx (operands[2], operands[1]));
|
||||
emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
; For each of these conversions, there is a define_expand, a define_insn
|
||||
; with a '#' template, and a define_split (with C code). The idea is
|
||||
|
@ -6455,7 +6586,7 @@
|
|||
|
||||
(define_expand "floatsidf2"
|
||||
[(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
|
||||
(float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
|
||||
(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
|
||||
(use (match_dup 2))
|
||||
(use (match_dup 3))
|
||||
(clobber (match_dup 4))
|
||||
|
@ -6467,19 +6598,31 @@
|
|||
{
|
||||
if (TARGET_E500_DOUBLE)
|
||||
{
|
||||
if (!REG_P (operands[1]))
|
||||
operands[1] = force_reg (SImode, operands[1]);
|
||||
emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
|
||||
DONE;
|
||||
}
|
||||
if (TARGET_POWERPC64)
|
||||
else if (TARGET_LFIWAX && TARGET_FCFID)
|
||||
{
|
||||
rtx x = convert_to_mode (DImode, operands[1], 0);
|
||||
emit_insn (gen_floatdidf2 (operands[0], x));
|
||||
rs6000_expand_convert_si_to_sfdf (operands[0], operands[1], false);
|
||||
DONE;
|
||||
}
|
||||
else if (TARGET_FCFID)
|
||||
{
|
||||
rtx dreg = operands[1];
|
||||
if (!REG_P (dreg))
|
||||
dreg = force_reg (SImode, dreg);
|
||||
dreg = convert_to_mode (DImode, dreg, false);
|
||||
emit_insn (gen_floatdidf2 (operands[0], dreg));
|
||||
DONE;
|
||||
}
|
||||
|
||||
if (!REG_P (operands[1]))
|
||||
operands[1] = force_reg (SImode, operands[1]);
|
||||
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
|
||||
operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
|
||||
operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
|
||||
operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
|
||||
operands[5] = gen_reg_rtx (DFmode);
|
||||
operands[6] = gen_reg_rtx (SImode);
|
||||
}")
|
||||
|
@ -6492,7 +6635,7 @@
|
|||
(clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
|
||||
(clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
|
||||
(clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
|
||||
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
||||
"! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
||||
"#"
|
||||
""
|
||||
[(pc)]
|
||||
|
@ -6518,37 +6661,79 @@
|
|||
}"
|
||||
[(set_attr "length" "24")])
|
||||
|
||||
;; If we don't have a direct conversion to single precision, don't enable this
|
||||
;; conversion for 32-bit without fast math, because we don't have the insn to
|
||||
;; generate the fixup swizzle to avoid double rounding problems.
|
||||
(define_expand "floatunssisf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "")
|
||||
(unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
|
||||
"")
|
||||
(unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
|
||||
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
|
||||
&& (!TARGET_FPRS
|
||||
|| (TARGET_FPRS
|
||||
&& ((TARGET_FCFIDUS && TARGET_LFIWZX)
|
||||
|| (TARGET_DOUBLE_FLOAT && TARGET_FCFID
|
||||
&& (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
|
||||
"
|
||||
{
|
||||
if (!TARGET_FPRS)
|
||||
{
|
||||
if (!REG_P (operands[1]))
|
||||
operands[1] = force_reg (SImode, operands[1]);
|
||||
}
|
||||
else if (TARGET_LFIWZX && TARGET_FCFIDUS)
|
||||
{
|
||||
rs6000_expand_convert_si_to_sfdf (operands[0], operands[1], true);
|
||||
DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx dreg = operands[1];
|
||||
if (!REG_P (dreg))
|
||||
dreg = force_reg (SImode, dreg);
|
||||
dreg = convert_to_mode (DImode, dreg, true);
|
||||
emit_insn (gen_floatdisf2 (operands[0], dreg));
|
||||
DONE;
|
||||
}
|
||||
}")
|
||||
|
||||
(define_expand "floatunssidf2"
|
||||
[(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
|
||||
(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
|
||||
(unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
|
||||
(use (match_dup 2))
|
||||
(use (match_dup 3))
|
||||
(clobber (match_dup 4))
|
||||
(clobber (match_dup 5))])]
|
||||
"TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
|
||||
"TARGET_HARD_FLOAT
|
||||
&& ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
|
||||
"
|
||||
{
|
||||
if (TARGET_E500_DOUBLE)
|
||||
{
|
||||
if (!REG_P (operands[1]))
|
||||
operands[1] = force_reg (SImode, operands[1]);
|
||||
emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
|
||||
DONE;
|
||||
}
|
||||
if (TARGET_POWERPC64)
|
||||
else if (TARGET_LFIWZX && TARGET_FCFID)
|
||||
{
|
||||
rtx x = convert_to_mode (DImode, operands[1], 1);
|
||||
emit_insn (gen_floatdidf2 (operands[0], x));
|
||||
rs6000_expand_convert_si_to_sfdf (operands[0], operands[1], true);
|
||||
DONE;
|
||||
}
|
||||
else if (TARGET_FCFID)
|
||||
{
|
||||
rtx dreg = operands[1];
|
||||
if (!REG_P (dreg))
|
||||
dreg = force_reg (SImode, dreg);
|
||||
dreg = convert_to_mode (DImode, dreg, true);
|
||||
emit_insn (gen_floatdidf2 (operands[0], dreg));
|
||||
DONE;
|
||||
}
|
||||
|
||||
if (!REG_P (operands[1]))
|
||||
operands[1] = force_reg (SImode, operands[1]);
|
||||
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
|
||||
operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
|
||||
operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
|
||||
operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
|
||||
operands[5] = gen_reg_rtx (DFmode);
|
||||
}")
|
||||
|
||||
|
@ -6559,7 +6744,8 @@
|
|||
(use (match_operand:DF 3 "gpc_reg_operand" "d"))
|
||||
(clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
|
||||
(clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
|
||||
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
||||
"! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
||||
&& !(TARGET_FCFID && TARGET_POWERPC64)"
|
||||
"#"
|
||||
""
|
||||
[(pc)]
|
||||
|
@ -6583,46 +6769,85 @@
|
|||
}"
|
||||
[(set_attr "length" "20")])
|
||||
|
||||
(define_expand "fix_truncdfsi2"
|
||||
[(parallel [(set (match_operand:SI 0 "fix_trunc_dest_operand" "")
|
||||
(fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
|
||||
(clobber (match_dup 2))
|
||||
(clobber (match_dup 3))])]
|
||||
"(TARGET_POWER2 || TARGET_POWERPC)
|
||||
&& TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
|
||||
(define_expand "fix_trunc<mode>si2"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
|
||||
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT
|
||||
&& ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
|
||||
"
|
||||
{
|
||||
if (TARGET_E500_DOUBLE)
|
||||
if (!<E500_CONVERT>)
|
||||
{
|
||||
emit_insn (gen_spe_fix_truncdfsi2 (operands[0], operands[1]));
|
||||
DONE;
|
||||
}
|
||||
operands[2] = gen_reg_rtx (DImode);
|
||||
if (TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
|
||||
&& gpc_reg_operand(operands[0], GET_MODE (operands[0])))
|
||||
{
|
||||
operands[3] = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_fix_truncdfsi2_mfpgpr (operands[0], operands[1],
|
||||
operands[2], operands[3]));
|
||||
rtx tmp, stack;
|
||||
|
||||
if (TARGET_STFIWX)
|
||||
{
|
||||
tmp = gen_reg_rtx (DImode);
|
||||
stack = rs6000_allocate_stack_temp (SImode, false, true);
|
||||
emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1],
|
||||
tmp, stack));
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = gen_reg_rtx (DImode);
|
||||
stack = rs6000_allocate_stack_temp (DImode, true, false);
|
||||
emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
|
||||
tmp, stack));
|
||||
}
|
||||
DONE;
|
||||
}
|
||||
if (TARGET_PPC_GFXOPT)
|
||||
{
|
||||
rtx orig_dest = operands[0];
|
||||
if (! memory_operand (orig_dest, GET_MODE (orig_dest)))
|
||||
operands[0] = assign_stack_temp (SImode, GET_MODE_SIZE (SImode), 0);
|
||||
emit_insn (gen_fix_truncdfsi2_internal_gfxopt (operands[0], operands[1],
|
||||
operands[2]));
|
||||
if (operands[0] != orig_dest)
|
||||
emit_move_insn (orig_dest, operands[0]);
|
||||
DONE;
|
||||
}
|
||||
operands[3] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
|
||||
}")
|
||||
|
||||
(define_insn_and_split "*fix_truncdfsi2_internal"
|
||||
(define_insn_and_split "fix_trunc<mode>si2_stfiwx"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
||||
(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d")))
|
||||
(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")))
|
||||
(clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
|
||||
(clobber (match_operand:SI 3 "indexed_or_indirect_operand" "=Z"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
||||
&& (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
|
||||
&& TARGET_STFIWX"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
|
||||
if (TARGET_MFPGPR && TARGET_POWERPC64 && REG_P (operands[0])
|
||||
&& INT_REGNO_P (REGNO (operands[0])))
|
||||
{
|
||||
rtx reg = gen_lowpart (DImode, operands[0]);
|
||||
emit_move_insn (reg, operands[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_insn (gen_stfiwx (operands[3], operands[2]));
|
||||
emit_move_insn (operands[0], operands[3]);
|
||||
}
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "12")])
|
||||
|
||||
(define_insn_and_split "*fix_trunc<mode>si2_mem"
|
||||
[(set (match_operand:SI 0 "memory_operand" "=Z")
|
||||
(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")))
|
||||
(clobber (match_scratch:DI 2 "=d"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
||||
&& (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
|
||||
&& TARGET_STFIWX"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
|
||||
emit_insn (gen_stfiwx (operands[0], operands[2]));
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
(define_insn_and_split "fix_trunc<mode>si2_internal"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
||||
(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<rreg>")))
|
||||
(clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
|
||||
(clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))]
|
||||
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
|
||||
|
@ -6636,143 +6861,194 @@
|
|||
gcc_assert (MEM_P (operands[3]));
|
||||
lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
|
||||
|
||||
emit_insn (gen_fctiwz (operands[2], operands[1]));
|
||||
emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
|
||||
emit_move_insn (operands[3], operands[2]);
|
||||
emit_move_insn (operands[0], lowword);
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "16")])
|
||||
|
||||
(define_insn_and_split "fix_truncdfsi2_internal_gfxopt"
|
||||
[(set (match_operand:SI 0 "memory_operand" "=Z")
|
||||
(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d")))
|
||||
(clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))]
|
||||
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
|
||||
&& TARGET_DOUBLE_FLOAT
|
||||
&& TARGET_PPC_GFXOPT"
|
||||
(define_expand "fix_trunc<mode>di2"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "")
|
||||
(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
|
||||
&& TARGET_FCFID"
|
||||
"")
|
||||
|
||||
(define_insn "*fix_trunc<mode>di2_fctidz"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
|
||||
(fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
|
||||
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
|
||||
&& TARGET_FCFID && !VECTOR_UNIT_VSX_P (<MODE>mode)"
|
||||
"fctidz %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_expand "fixuns_trunc<mode>si2"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_HARD_FLOAT
|
||||
&& ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
|
||||
|| <E500_CONVERT>)"
|
||||
"
|
||||
{
|
||||
if (!<E500_CONVERT>)
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (DImode);
|
||||
rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
|
||||
emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1],
|
||||
tmp, stack));
|
||||
DONE;
|
||||
}
|
||||
}")
|
||||
|
||||
(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
||||
(unsigned_fix:SI
|
||||
(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")))
|
||||
(clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
|
||||
(clobber (match_operand:SI 3 "indexed_or_indirect_operand" "=Z"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
|
||||
&& TARGET_STFIWX"
|
||||
"#"
|
||||
"&& 1"
|
||||
"&& reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
emit_insn (gen_fctiwz (operands[2], operands[1]));
|
||||
emit_insn (gen_fctiwuz_<mode> (operands[2], operands[1]));
|
||||
if (TARGET_MFPGPR && TARGET_POWERPC64 && REG_P (operands[0])
|
||||
&& INT_REGNO_P (REGNO (operands[0])))
|
||||
{
|
||||
rtx reg = gen_lowpart (DImode, operands[0]);
|
||||
emit_move_insn (reg, operands[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_insn (gen_stfiwx (operands[3], operands[2]));
|
||||
emit_move_insn (operands[0], operands[3]);
|
||||
}
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "12")])
|
||||
|
||||
(define_insn_and_split "*fixuns_trunc<mode>si2_mem"
|
||||
[(set (match_operand:SI 0 "memory_operand" "=Z")
|
||||
(unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")))
|
||||
(clobber (match_scratch:DI 2 "=d"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
|
||||
&& TARGET_STFIWX"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
emit_insn (gen_fctiwuz_<mode> (operands[2], operands[1]));
|
||||
emit_insn (gen_stfiwx (operands[0], operands[2]));
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "16")])
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
(define_insn_and_split "fix_truncdfsi2_mfpgpr"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
||||
(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d")))
|
||||
(clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
|
||||
(clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))]
|
||||
"TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
|
||||
&& TARGET_DOUBLE_FLOAT"
|
||||
"#"
|
||||
"&& 1"
|
||||
[(set (match_dup 2) (unspec:DI [(fix:SI (match_dup 1))] UNSPEC_FCTIWZ))
|
||||
(set (match_dup 3) (match_dup 2))
|
||||
(set (match_dup 0) (subreg:SI (match_dup 3) 4))]
|
||||
""
|
||||
[(set_attr "length" "12")])
|
||||
(define_expand "fixuns_trunc<mode>di2"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
(unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
|
||||
"TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
|
||||
"")
|
||||
|
||||
(define_insn "*fixuns_trunc<mode>di2_fctiduz"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
|
||||
(unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
|
||||
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
|
||||
&& TARGET_FCTIDUZ && !VECTOR_UNIT_VSX_P (<MODE>mode)"
|
||||
"fctiduz %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
|
||||
; rather than (set (subreg:SI (reg)) (fix:SI ...))
|
||||
; because the first makes it clear that operand 0 is not live
|
||||
; before the instruction.
|
||||
(define_insn "fctiwz"
|
||||
(define_insn "fctiwz_<mode>"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
|
||||
(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))]
|
||||
(unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))]
|
||||
UNSPEC_FCTIWZ))]
|
||||
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
|
||||
&& TARGET_DOUBLE_FLOAT"
|
||||
"{fcirz|fctiwz} %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_expand "btruncdf2"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
||||
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIZ))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
||||
(define_insn "fctiwuz_<mode>"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
|
||||
(unspec:DI [(unsigned_fix:SI
|
||||
(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>"))]
|
||||
UNSPEC_FCTIWUZ))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
|
||||
"fctiwuz %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
;; No VSX equivalent to fctid
|
||||
(define_insn "lrint<mode>di2"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
|
||||
(unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
|
||||
UNSPEC_FCTID))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
|
||||
"fctid %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_expand "btrunc<mode>2"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
|
||||
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
|
||||
UNSPEC_FRIZ))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
|
||||
"")
|
||||
|
||||
(define_insn "*btruncdf2_fpr"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
||||
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
||||
&& !VECTOR_UNIT_VSX_P (DFmode)"
|
||||
(define_insn "*btrunc<mode>2_fpr"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
|
||||
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
|
||||
UNSPEC_FRIZ))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
|
||||
&& !VECTOR_UNIT_VSX_P (<MODE>mode)"
|
||||
"friz %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "btruncsf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
|
||||
"friz %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_expand "ceildf2"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "")
|
||||
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIP))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
||||
(define_expand "ceil<mode>2"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
|
||||
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
|
||||
UNSPEC_FRIP))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
|
||||
"")
|
||||
|
||||
(define_insn "*ceildf2_fpr"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
||||
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIP))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
||||
&& !VECTOR_UNIT_VSX_P (DFmode)"
|
||||
(define_insn "*ceil<mode>2_fpr"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
|
||||
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
|
||||
UNSPEC_FRIP))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
|
||||
&& !VECTOR_UNIT_VSX_P (<MODE>mode)"
|
||||
"frip %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "ceilsf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
|
||||
"frip %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_expand "floordf2"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "")
|
||||
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIM))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
||||
(define_expand "floor<mode>2"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "")
|
||||
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
|
||||
UNSPEC_FRIM))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
|
||||
"")
|
||||
|
||||
(define_insn "*floordf2_fpr"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
||||
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIM))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
||||
&& !VECTOR_UNIT_VSX_P (DFmode)"
|
||||
"frim %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "floorsf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
|
||||
(define_insn "*floor<mode>2_fpr"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
|
||||
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
|
||||
UNSPEC_FRIM))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
|
||||
&& !VECTOR_UNIT_VSX_P (<MODE>mode)"
|
||||
"frim %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
;; No VSX equivalent to frin
|
||||
(define_insn "rounddf2"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
||||
(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIN))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
||||
(define_insn "round<mode>2"
|
||||
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
|
||||
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
|
||||
UNSPEC_FRIN))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
|
||||
"frin %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "roundsf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
|
||||
"TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
|
||||
"frin %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_expand "ftruncdf2"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "")
|
||||
(fix:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
|
||||
"VECTOR_UNIT_VSX_P (DFmode)"
|
||||
"")
|
||||
|
||||
; An UNSPEC is used so we don't have to support SImode in FP registers.
|
||||
(define_insn "stfiwx"
|
||||
[(set (match_operand:SI 0 "memory_operand" "=Z")
|
||||
|
@ -6782,76 +7058,154 @@
|
|||
"stfiwx %1,%y0"
|
||||
[(set_attr "type" "fpstore")])
|
||||
|
||||
;; If we don't have a direct conversion to single precision, don't enable this
|
||||
;; conversion for 32-bit without fast math, because we don't have the insn to
|
||||
;; generate the fixup swizzle to avoid double rounding problems.
|
||||
(define_expand "floatsisf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "")
|
||||
(float:SF (match_operand:SI 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_HARD_FLOAT && !TARGET_FPRS"
|
||||
"")
|
||||
(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
|
||||
"TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
|
||||
&& (!TARGET_FPRS
|
||||
|| (TARGET_FPRS
|
||||
&& ((TARGET_FCFIDS && TARGET_LFIWAX)
|
||||
|| (TARGET_DOUBLE_FLOAT && TARGET_FCFID
|
||||
&& (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
|
||||
"
|
||||
{
|
||||
if (!TARGET_FPRS)
|
||||
{
|
||||
if (!REG_P (operands[1]))
|
||||
operands[1] = force_reg (SImode, operands[1]);
|
||||
}
|
||||
else if (TARGET_FCFIDS && TARGET_LFIWAX)
|
||||
{
|
||||
rs6000_expand_convert_si_to_sfdf (operands[0], operands[1], false);
|
||||
DONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx dreg = operands[1];
|
||||
if (!REG_P (dreg))
|
||||
dreg = force_reg (SImode, dreg);
|
||||
dreg = convert_to_mode (DImode, dreg, false);
|
||||
emit_insn (gen_floatdisf2 (operands[0], dreg));
|
||||
DONE;
|
||||
}
|
||||
}")
|
||||
|
||||
(define_expand "floatdidf2"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "")
|
||||
(float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
|
||||
"(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode))
|
||||
&& TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
|
||||
"TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
|
||||
"")
|
||||
|
||||
(define_insn "*floatdidf2_fpr"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
||||
(float:DF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))]
|
||||
"(TARGET_POWERPC64 || TARGET_XILINX_FPU)
|
||||
&& TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
|
||||
(float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))]
|
||||
"TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
|
||||
&& !VECTOR_UNIT_VSX_P (DFmode)"
|
||||
"fcfid %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
; Allow the combiner to merge source memory operands to the conversion so that
|
||||
; the optimizer/register allocator doesn't try to load the value too early in a
|
||||
; GPR and then use store/load to move it to a FPR and suffer from a store-load
|
||||
; hit. We will split after reload to avoid the trip through the GPRs
|
||||
|
||||
(define_insn_and_split "*floatdidf2_mem"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
||||
(float:DF (match_operand:DI 1 "memory_operand" "m")))
|
||||
(clobber (match_scratch:DI 2 "=d"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 2) (match_dup 1))
|
||||
(set (match_dup 0) (float:DF (match_dup 2)))]
|
||||
""
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
(define_expand "floatunsdidf2"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "")
|
||||
(unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_VSX"
|
||||
(unsigned_float:DF
|
||||
(match_operand:DI 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode)"
|
||||
"")
|
||||
|
||||
(define_expand "fix_truncdfdi2"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "")
|
||||
(fix:DI (match_operand:DF 1 "gpc_reg_operand" "")))]
|
||||
"(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode))
|
||||
&& TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
|
||||
"")
|
||||
(define_insn "*floatunsdidf2_fcfidu"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
||||
(unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))]
|
||||
"TARGET_FCFIDU && !VECTOR_UNIT_VSX_P (DFmode)"
|
||||
"fcfidu %0,%1"
|
||||
[(set_attr "type" "fp")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn "*fix_truncdfdi2_fpr"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=!d#r")
|
||||
(fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))]
|
||||
"(TARGET_POWERPC64 || TARGET_XILINX_FPU)
|
||||
&& TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
|
||||
&& !VECTOR_UNIT_VSX_P (DFmode)"
|
||||
"fctidz %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
(define_insn_and_split "*floatunsdidf2_mem"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
||||
(unsigned_float:DF (match_operand:DI 1 "memory_operand" "m")))
|
||||
(clobber (match_scratch:DI 2 "=d"))]
|
||||
"TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode)"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 2) (match_dup 1))
|
||||
(set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
|
||||
""
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
(define_expand "floatdisf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "")
|
||||
(float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
|
||||
"TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
|
||||
&& (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
|
||||
"
|
||||
{
|
||||
rtx val = operands[1];
|
||||
if (!flag_unsafe_math_optimizations)
|
||||
if (!TARGET_FCFIDS)
|
||||
{
|
||||
rtx label = gen_label_rtx ();
|
||||
val = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
|
||||
emit_label (label);
|
||||
rtx val = operands[1];
|
||||
if (!flag_unsafe_math_optimizations)
|
||||
{
|
||||
rtx label = gen_label_rtx ();
|
||||
val = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
|
||||
emit_label (label);
|
||||
}
|
||||
emit_insn (gen_floatdisf2_internal1 (operands[0], val));
|
||||
DONE;
|
||||
}
|
||||
emit_insn (gen_floatdisf2_internal1 (operands[0], val));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "floatdisf2_fcfids"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
(float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
|
||||
&& TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
|
||||
"fcfids %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn_and_split "*floatdisf2_mem"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
(float:SF (match_operand:DI 1 "memory_operand" "m")))
|
||||
(clobber (match_scratch:DI 2 "=f"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
|
||||
&& TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
emit_move_insn (operands[2], operands[1]);
|
||||
emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
;; This is not IEEE compliant if rounding mode is "round to nearest".
|
||||
;; If the DI->DF conversion is inexact, then it's possible to suffer
|
||||
;; from double rounding.
|
||||
(define_insn_and_split "floatdisf2_internal1"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
(float:SF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))
|
||||
(float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
|
||||
(clobber (match_scratch:DF 2 "=d"))]
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
|
||||
"TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 2)
|
||||
|
@ -6891,6 +7245,38 @@
|
|||
operands[3] = gen_reg_rtx (DImode);
|
||||
operands[4] = gen_reg_rtx (CCUNSmode);
|
||||
}")
|
||||
|
||||
(define_expand "floatunsdisf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "")
|
||||
(unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
|
||||
&& TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
|
||||
"")
|
||||
|
||||
(define_insn "floatunsdisf2_fcfidus"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
(unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
|
||||
&& TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
|
||||
"fcfidus %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn_and_split "*floatunsdisf2_mem"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
(unsigned_float:SF (match_operand:DI 1 "memory_operand" "m")))
|
||||
(clobber (match_scratch:DI 2 "=f"))]
|
||||
"TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
|
||||
&& TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(pc)]
|
||||
"
|
||||
{
|
||||
emit_move_insn (operands[2], operands[1]);
|
||||
emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
|
||||
DONE;
|
||||
}"
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
;; Define the DImode operations that can be done in a small number
|
||||
;; of instructions. The & constraints are to prevent the register
|
||||
|
@ -9540,7 +9926,7 @@
|
|||
gcc_assert (MEM_P (operands[5]));
|
||||
lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
|
||||
|
||||
emit_insn (gen_fctiwz (operands[4], operands[2]));
|
||||
emit_insn (gen_fctiwz_df (operands[4], operands[2]));
|
||||
emit_move_insn (operands[5], operands[4]);
|
||||
emit_move_insn (operands[0], lowword);
|
||||
DONE;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
;; VSX patterns.
|
||||
;; Copyright (C) 2009
|
||||
;; Copyright (C) 2009, 2010
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
|
@ -73,11 +73,11 @@
|
|||
;; Map the register class used for float<->int conversions
|
||||
(define_mode_attr VSr2 [(V2DF "wd")
|
||||
(V4SF "wf")
|
||||
(DF "!f#r")])
|
||||
(DF "ws")])
|
||||
|
||||
(define_mode_attr VSr3 [(V2DF "wa")
|
||||
(V4SF "wa")
|
||||
(DF "!f#r")])
|
||||
(DF "ws")])
|
||||
|
||||
;; Map the register class for sp<->dp float conversions, destination
|
||||
(define_mode_attr VSr4 [(SF "ws")
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
2010-08-23 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
* gcc.target/powerpc/ppc-fpconv-1.c: New test for integer to
|
||||
floating point conversion code generation.
|
||||
* gcc.target/powerpc/ppc-fpconv-2.c: Ditto.
|
||||
* gcc.target/powerpc/ppc-fpconv-3.c: Ditto.
|
||||
* gcc.target/powerpc/ppc-fpconv-4.c: Ditto.
|
||||
* gcc.target/powerpc/ppc-fpconv-5.c: New test for floating point
|
||||
to integer conversion code generation.
|
||||
* gcc.target/powerpc/ppc-fpconv-6.c: Ditto.
|
||||
* gcc.target/powerpc/ppc-fpconv-7.c: Ditto.
|
||||
* gcc.target/powerpc/ppc-fpconv-8.c: Ditto.
|
||||
* gcc.target/powerpc/ppc-fpconv-9.c: Ditto.
|
||||
|
||||
2010-08-27 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
|
||||
|
||||
PR fortran/32049
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_vsx_ok } */
|
||||
/* { dg-options "-O2 -mcpu=power7 -ffast-math" } */
|
||||
/* { dg-final { scan-assembler-times "lfiwax" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "lfiwzx" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "fcfids" 3 } } */
|
||||
/* { dg-final { scan-assembler-times "fcfidus" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "xscvsxddp" 3 } } */
|
||||
/* { dg-final { scan-assembler-times "xscvuxddp" 1 } } */
|
||||
|
||||
void int_to_float (float *dest, int *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void int_to_double (double *dest, int *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void uint_to_float (float *dest, unsigned int *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void uint_to_double (double *dest, unsigned int *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void llong_to_float (float *dest, long long *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void llong_to_double (double *dest, long long *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void ullong_to_float (float *dest, unsigned long long *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void ullong_to_double (double *dest, unsigned long long *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_vsx_ok } */
|
||||
/* { dg-options "-O2 -mcpu=power6 -ffast-math" } */
|
||||
/* { dg-final { scan-assembler-times "lfiwax" 1 } } */
|
||||
/* { dg-final { scan-assembler-not "lfiwzx" } } */
|
||||
/* { dg-final { scan-assembler-times "fcfid " 10 } } */
|
||||
/* { dg-final { scan-assembler-not "fcfids" } } */
|
||||
/* { dg-final { scan-assembler-not "fcfidus" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvsxddp" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvuxddp" } } */
|
||||
|
||||
void int_to_float (float *dest, int *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void int_to_double (double *dest, int *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void uint_to_float (float *dest, unsigned int *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void uint_to_double (double *dest, unsigned int *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void llong_to_float (float *dest, long long *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void llong_to_double (double *dest, long long *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void ullong_to_float (float *dest, unsigned long long *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void ullong_to_double (double *dest, unsigned long long *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target ilp32 } */
|
||||
/* { dg-options "-O2 -mcpu=power5 -ffast-math" } */
|
||||
/* { dg-final { scan-assembler-not "lfiwax" } } */
|
||||
/* { dg-final { scan-assembler-not "lfiwzx" } } */
|
||||
/* { dg-final { scan-assembler-times "fcfid " 10 } } */
|
||||
/* { dg-final { scan-assembler-not "fcfids" } } */
|
||||
/* { dg-final { scan-assembler-not "fcfidus" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvsxddp" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvuxddp" } } */
|
||||
|
||||
void int_to_float (float *dest, int *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void int_to_double (double *dest, int *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void uint_to_float (float *dest, unsigned int *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void uint_to_double (double *dest, unsigned int *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void llong_to_float (float *dest, long long *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void llong_to_double (double *dest, long long *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void ullong_to_float (float *dest, unsigned long long *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void ullong_to_double (double *dest, unsigned long long *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target ilp32 } */
|
||||
/* { dg-options "-O2 -mcpu=750 -ffast-math" } */
|
||||
/* { dg-final { scan-assembler-not "lfiwax" } } */
|
||||
/* { dg-final { scan-assembler-not "lfiwzx" } } */
|
||||
/* { dg-final { scan-assembler-not "fcfid " } } */
|
||||
/* { dg-final { scan-assembler-not "fcfids" } } */
|
||||
/* { dg-final { scan-assembler-not "fcfidus" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvsxddp" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvuxddp" } } */
|
||||
|
||||
void int_to_float (float *dest, int *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void int_to_double (double *dest, int *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void uint_to_float (float *dest, unsigned int *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void uint_to_double (double *dest, unsigned int *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void llong_to_float (float *dest, long long *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void llong_to_double (double *dest, long long *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
||||
|
||||
void ullong_to_float (float *dest, unsigned long long *src)
|
||||
{
|
||||
*dest = (float) *src;
|
||||
}
|
||||
|
||||
void ullong_to_double (double *dest, unsigned long long *src)
|
||||
{
|
||||
*dest = (double) *src;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_vsx_ok } */
|
||||
/* { dg-options "-O3 -mcpu=power7 -ffast-math" } */
|
||||
/* { dg-final { scan-assembler-times "fctiwz" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "fctiwuz" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "fctidz" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "fctiduz" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "xscvdpsxds" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "xscvdpuxds" 1 } } */
|
||||
|
||||
void float_to_int (int *dest, float src) { *dest = (int) src; }
|
||||
void double_to_int (int *dest, double src) { *dest = (int) src; }
|
||||
|
||||
void float_to_uint (int *dest, float src) { *dest = (unsigned int) src; }
|
||||
void double_to_uint (int *dest, double src) { *dest = (unsigned int) src; }
|
||||
|
||||
void float_to_llong (long long *dest, float src) { *dest = (long long) src; }
|
||||
void double_to_llong (long long *dest, double src) { *dest = (long long) src; }
|
||||
|
||||
void float_to_ullong (unsigned long long *dest, float src) { *dest = (unsigned long long) src; }
|
||||
void double_to_ullong (unsigned long long *dest, double src) { *dest = (unsigned long long) src; }
|
|
@ -0,0 +1,22 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_vsx_ok } */
|
||||
/* { dg-options "-O3 -mcpu=power6 -ffast-math" } */
|
||||
/* { dg-final { scan-assembler-times "fctiwz" 2 } } */
|
||||
/* { dg-final { scan-assembler-not "fctiwuz" } } */
|
||||
/* { dg-final { scan-assembler-times "fctidz" 8 } } */
|
||||
/* { dg-final { scan-assembler-not "fctiduz" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvdpsxds" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvdpuxds" } } */
|
||||
|
||||
void float_to_int (int *dest, float src) { *dest = (int) src; }
|
||||
void double_to_int (int *dest, double src) { *dest = (int) src; }
|
||||
|
||||
void float_to_uint (int *dest, float src) { *dest = (unsigned int) src; }
|
||||
void double_to_uint (int *dest, double src) { *dest = (unsigned int) src; }
|
||||
|
||||
void float_to_llong (long long *dest, float src) { *dest = (long long) src; }
|
||||
void double_to_llong (long long *dest, double src) { *dest = (long long) src; }
|
||||
|
||||
void float_to_ullong (unsigned long long *dest, float src) { *dest = (unsigned long long) src; }
|
||||
void double_to_ullong (unsigned long long *dest, double src) { *dest = (unsigned long long) src; }
|
|
@ -0,0 +1,22 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target ilp32 } */
|
||||
/* { dg-options "-O3 -mcpu=power5 -ffast-math" } */
|
||||
/* { dg-final { scan-assembler-times "fctiwz" 2 } } */
|
||||
/* { dg-final { scan-assembler-not "fctiwuz" } } */
|
||||
/* { dg-final { scan-assembler-times "fctidz" 8 } } */
|
||||
/* { dg-final { scan-assembler-not "fctiduz" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvdpsxds" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvdpuxds" } } */
|
||||
|
||||
void float_to_int (int *dest, float src) { *dest = (int) src; }
|
||||
void double_to_int (int *dest, double src) { *dest = (int) src; }
|
||||
|
||||
void float_to_uint (int *dest, float src) { *dest = (unsigned int) src; }
|
||||
void double_to_uint (int *dest, double src) { *dest = (unsigned int) src; }
|
||||
|
||||
void float_to_llong (long long *dest, float src) { *dest = (long long) src; }
|
||||
void double_to_llong (long long *dest, double src) { *dest = (long long) src; }
|
||||
|
||||
void float_to_ullong (unsigned long long *dest, float src) { *dest = (unsigned long long) src; }
|
||||
void double_to_ullong (unsigned long long *dest, double src) { *dest = (unsigned long long) src; }
|
|
@ -0,0 +1,22 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target ilp32 } */
|
||||
/* { dg-options "-O3 -mcpu=750 -ffast-math" } */
|
||||
/* { dg-final { scan-assembler-times "fctiwz" 6 } } */
|
||||
/* { dg-final { scan-assembler-not "fctiwuz" } } */
|
||||
/* { dg-final { scan-assembler-not "fctidz" } } */
|
||||
/* { dg-final { scan-assembler-not "fctiduz" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvdpsxds" } } */
|
||||
/* { dg-final { scan-assembler-not "xscvdpuxds" } } */
|
||||
|
||||
void float_to_int (int *dest, float src) { *dest = (int) src; }
|
||||
void double_to_int (int *dest, double src) { *dest = (int) src; }
|
||||
|
||||
void float_to_uint (int *dest, float src) { *dest = (unsigned int) src; }
|
||||
void double_to_uint (int *dest, double src) { *dest = (unsigned int) src; }
|
||||
|
||||
void float_to_llong (long long *dest, float src) { *dest = (long long) src; }
|
||||
void double_to_llong (long long *dest, double src) { *dest = (long long) src; }
|
||||
|
||||
void float_to_ullong (unsigned long long *dest, float src) { *dest = (unsigned long long) src; }
|
||||
void double_to_ullong (unsigned long long *dest, double src) { *dest = (unsigned long long) src; }
|
|
@ -0,0 +1,11 @@
|
|||
/* { dg-do compile { target { powerpc*-*-* } } } */
|
||||
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
|
||||
/* { dg-require-effective-target powerpc_vsx_ok } */
|
||||
/* { dg-options "-O3 -mcpu=power7 -ffast-math" } */
|
||||
/* { dg-final { scan-assembler-not "lwz" } } */
|
||||
/* { dg-final { scan-assembler-not "stw" } } */
|
||||
/* { dg-final { scan-assembler-not "ld " } } */
|
||||
/* { dg-final { scan-assembler-not "std" } } */
|
||||
|
||||
void float_to_llong (long long *dest, float src) { *dest = (long long) src; }
|
||||
void double_to_llong (long long *dest, double src) { *dest = (long long) src; }
|
Loading…
Reference in New Issue