From ecb62ae79bc32cd8bc6c2fb5b0c1299c728ea37c Mon Sep 17 00:00:00 2001 From: Geoffrey Keating Date: Thu, 8 Jan 2004 22:50:54 +0000 Subject: [PATCH] rs6000.md (cmptf_internal1): Correct branch offset. * config/rs6000/rs6000.md (cmptf_internal1): Correct branch offset. (UNSPEC_FIX_TRUNC_TF): New constant. (movtf_internal): Make splitter active only when insn is active. (extenddftf2): Rewrite to properly load zero into low part. (extenddftf2_internal): New. (extendsftf2): Rewrite. (truncdftf2): Correct length. (floatditf2): Delete. (fix_trunc_helper): New. (fix_trunctfdi2): Use fix_trunc_helper. (fix_trunctfsi2): Likewise.fix_trunc (fix_trunctfsi2_internal): New. From-SVN: r75559 --- gcc/ChangeLog | 13 ++++ gcc/config/rs6000/rs6000.md | 145 +++++++++++++++++++++++------------- 2 files changed, 108 insertions(+), 50 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6fa70255857..4608ecaedfd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,18 @@ 2004-01-08 Geoffrey Keating + * config/rs6000/rs6000.md (cmptf_internal1): Correct branch offset. + (UNSPEC_FIX_TRUNC_TF): New constant. + (movtf_internal): Make splitter active only when insn is active. + (extenddftf2): Rewrite to properly load zero into low part. + (extenddftf2_internal): New. + (extendsftf2): Rewrite. + (truncdftf2): Correct length. + (floatditf2): Delete. + (fix_trunc_helper): New. + (fix_trunctfdi2): Use fix_trunc_helper. + (fix_trunctfsi2): Likewise.fix_trunc + (fix_trunctfsi2_internal): New. + * config/rs6000/rs6000.c (legitimate_lo_sum_address_p): lo_sum addresses are legitimate on Darwin even when flag_pic. (rs6000_legitimize_reload_address) [TARGET_MACHO]: Don't create diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 273aec6878e..bc7ecefefb1 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -49,6 +49,7 @@ (UNSPEC_TLSTPRELLO 27) (UNSPEC_TLSGOTTPREL 28) (UNSPEC_TLSTLS 29) + (UNSPEC_FIX_TRUNC_TF 30) ; fadd, rounding towards zero ]) ;; @@ -5210,7 +5211,7 @@ (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)) @@ -5225,7 +5226,7 @@ (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)) @@ -8219,38 +8220,51 @@ && (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") @@ -8259,7 +8273,7 @@ && 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") @@ -8275,21 +8289,6 @@ (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")))] @@ -8302,30 +8301,76 @@ 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; }) @@ -11228,7 +11273,7 @@ (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")]) -- 2.30.2