===================================================================
@@ -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 @@ (define_mode_attr VSr [(V16QI "v")
;; 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")
===================================================================
@@ -6435,30 +6435,6 @@ (define_insn "*fselsfdf4"
;; 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"
- "")
-
-(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_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_expand "fixuns_truncdfdi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
- "TARGET_HARD_FLOAT && TARGET_VSX"
- "")
-
; 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"
@@ -6793,46 +6769,85 @@ (define_insn_and_split "*floatunssidf2_i
}"
[(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)
+}")
+
+(define_insn_and_split "fix_trunc<mode>si2_stfiwx"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (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 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;
+ rtx reg = gen_lowpart (DImode, operands[0]);
+ emit_move_insn (reg, operands[2]);
}
- operands[3] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
-}")
+ 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_truncdfsi2_internal"
+(define_insn_and_split "fix_trunc<mode>si2_internal"
[(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" "<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
@@ -6846,143 +6861,194 @@ (define_insn_and_split "*fix_truncdfsi2_
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"
+(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"
+ "#"
+ "&& reload_completed"
+ [(pc)]
+ "
+{
+ 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")
- (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"
+ (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"
"#"
- "&& 1"
+ "&& reload_completed"
[(pc)]
"
{
- emit_insn (gen_fctiwz (operands[2], operands[1]));
+ 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 "*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)"
- "friz %0,%1"
+(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")])
-(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"
+;; 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 "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 "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 "*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)"
- "frip %0,%1"
+(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 "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 "
+(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 "*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_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"
- "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 "
+(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_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")
@@ -9860,7 +9926,7 @@ (define_insn_and_split "*fix_trunctfsi2_
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;
===================================================================
@@ -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; }
===================================================================
@@ -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; }