(UNSPEC_TLSTPRELLO 27)
(UNSPEC_TLSGOTTPREL 28)
(UNSPEC_TLSTLS 29)
+ (UNSPEC_FIX_TRUNC_TF 30) ; fadd, rounding towards zero
])
;;
(clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
- ""
+ "&& 1"
[(set (match_dup 3) (sign_extend:DI (match_dup 1)))
(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 2))
(clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
- ""
+ "&& 1"
[(set (match_dup 3) (zero_extend:DI (match_dup 1)))
(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 2))
&& (gpc_reg_operand (operands[0], TFmode)
|| gpc_reg_operand (operands[1], TFmode))"
"#"
- "reload_completed"
+ "&& reload_completed"
[(pc)]
{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
[(set_attr "length" "8,8,8,20,20")])
-(define_insn "extenddftf2"
- [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "f")))]
+(define_expand "extenddftf2"
+ [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (float_extend:TF (match_operand:DF 1 "input_operand" "")))
+ (use (match_dup 2))])]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
- "*
{
- if (REGNO (operands[0]) == REGNO (operands[1]))
- return \"fsub %L0,%L0,%L0\";
- else
- return \"fmr %0,%1\;fsub %L0,%L0,%L0\";
-}"
- [(set_attr "type" "fp")])
+ operands[2] = CONST0_RTX (DFmode);
+})
-(define_insn "extendsftf2"
- [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "f")))]
+(define_insn_and_split "*extenddftf2_internal"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,&f,r")
+ (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF")))
+ (use (match_operand:DF 2 "input_operand" "rf,m,f,n"))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
- "*
+ "#"
+ "&& reload_completed"
+ [(pc)]
{
- if (REGNO (operands[0]) == REGNO (operands[1]))
- return \"fsub %L0,%L0,%L0\";
- else
- return \"fmr %0,%1\;fsub %L0,%L0,%L0\";
-}"
- [(set_attr "type" "fp")])
+ const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
+ const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
+ emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
+ operands[1]);
+ emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
+ operands[2]);
+ DONE;
+})
+
+(define_expand "extendsftf2"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+{
+ rtx tmp = gen_reg_rtx (DFmode);
+ emit_insn (gen_extendsfdf2 (tmp, operands[1]));
+ emit_insn (gen_extenddftf2 (operands[0], tmp));
+ DONE;
+})
(define_insn "trunctfdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"fadd %0,%1,%L1"
[(set_attr "type" "fp")
- (set_attr "length" "8")])
+ (set_attr "length" "4")])
(define_insn_and_split "trunctfsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(float_truncate:SF (match_dup 2)))]
"")
-(define_insn_and_split "floatditf2"
- [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (float:TF (match_operand:DI 1 "gpc_reg_operand" "*f")))
- (clobber (match_scratch:DF 2 "=f"))]
- "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
- && TARGET_POWERPC64
- && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
- "#"
- "&& reload_completed"
- [(set (match_dup 2)
- (float:DF (match_dup 1)))
- (set (match_dup 0)
- (float_extend:TF (match_dup 2)))]
- "")
-
(define_expand "floatsitf2"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
(float:TF (match_operand:SI 1 "gpc_reg_operand" "r")))]
DONE;
})
+; fadd, but rounding towards zero.
+; This is probably not the optimal code sequence.
+(define_insn "fix_trunc_helper"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")]
+ UNSPEC_FIX_TRUNC_TF))
+ (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS"
+ "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
+ [(set_attr "type" "fp")
+ (set_attr "length" "20")])
+
(define_insn_and_split "fix_trunctfdi2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
(fix:DI (match_operand:TF 1 "gpc_reg_operand" "f")))
- (clobber (match_scratch:DF 2 "=f"))]
+ (clobber (match_scratch:DF 2 "=f"))
+ (clobber (match_scratch:DF 3 "=&f"))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
&& TARGET_POWERPC64
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"#"
"&& reload_completed"
- [(set (match_dup 2)
- (float_truncate:DF (match_dup 1)))
- (set (match_dup 0)
- (fix:DI (match_dup 2)))]
- "")
+ [(pc)]
+{
+ emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
+ emit_insn (gen_fix_truncdfdi2 (operands[0], operands[2]));
+})
(define_expand "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))
+ (clobber (match_dup 5))])]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && (TARGET_POWER2 || TARGET_POWERPC)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+{
+ operands[2] = gen_reg_rtx (DFmode);
+ operands[3] = gen_reg_rtx (DFmode);
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
+})
+
+(define_insn_and_split "*fix_trunctfsi2_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))]
+ (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))
+ (clobber (match_operand:DF 2 "gpc_reg_operand" "=f"))
+ (clobber (match_operand:DF 3 "gpc_reg_operand" "=&f"))
+ (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))
+ (clobber (match_operand:DI 5 "memory_operand" "=o"))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "#"
+ "&& reload_completed"
+ [(pc)]
{
- rtx tmp = gen_reg_rtx (DFmode);
- emit_insn (gen_trunctfdf2 (tmp, operands[1]));
- expand_fix (operands[0], tmp, false);
+ rtx lowword;
+ emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
+
+ if (GET_CODE (operands[5]) != MEM)
+ abort();
+ lowword = XEXP (operands[5], 0);
+ if (WORDS_BIG_ENDIAN)
+ lowword = plus_constant (lowword, 4);
+
+ emit_insn (gen_fctiwz (operands[4], operands[2]));
+ emit_move_insn (operands[5], operands[4]);
+ emit_move_insn (operands[0], gen_rtx_MEM (SImode, lowword));
DONE;
})
(match_operand:TF 2 "gpc_reg_operand" "f")))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
- "fcmpu %0,%1,%2\;bne %0,$+4\;fcmpu %0,%L1,%L2"
+ "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
[(set_attr "type" "fpcompare")
(set_attr "length" "12")])
\f