* config/rs6000/rs6000.md (cmptf_internal1): Correct branch offset.
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Jan 2004 22:50:54 +0000 (22:50 +0000)
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Jan 2004 22:50:54 +0000 (22:50 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@75559 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/rs6000.md

index 6fa7025..4608eca 100644 (file)
@@ -1,5 +1,18 @@
 2004-01-08  Geoffrey Keating  <geoffk@apple.com>
 
+       * 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
index 273aec6..bc7ecef 100644 (file)
@@ -49,6 +49,7 @@
    (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