rs6000.c (rs6000_hard_regno_mode_ok): Force TDmode regnos into even/odd register...
authorPeter Bergner <bergner@vnet.ibm.com>
Tue, 17 Apr 2007 16:07:05 +0000 (11:07 -0500)
committerPeter Bergner <bergner@gcc.gnu.org>
Tue, 17 Apr 2007 16:07:05 +0000 (11:07 -0500)
* config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): Force TDmode
regnos into even/odd register pairs.
* config/rs6000/rs6000.h [SLOW_UNALIGNED_ACCESS]: Treat DDmode and
TDmode similar to the other floating point modes.
[SECONDARY_MEMORY_NEEDED]: Treat DDmode similar to DFmode.
* config/rs6000/dfp.md (negdd2, absdd2, negtd2, abstd2): New
define_expand's.
(negdd2_fpr, absdd2_fpr, nabsdd2_fpr, negtd2_fpr, abstd2_fpr,
nabstd2_fpr, movdd_hardfloat64_mfpgpr): New define_insn's.
(movdd_hardfloat64): Use TARGET_MFPGPR.

From-SVN: r123916

gcc/ChangeLog
gcc/config/rs6000/dfp.md
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h

index a315b6f4eb498060c082753f3b3ddf2a59fa7d27..19525a3ff030f145f0a356bbd983547e56c34a3d 100644 (file)
@@ -1,3 +1,16 @@
+2007-04-17  Peter Bergner  <bergner@vnet.ibm.com>
+
+       * config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): Force TDmode
+       regnos into even/odd register pairs.
+       * config/rs6000/rs6000.h [SLOW_UNALIGNED_ACCESS]: Treat DDmode and
+       TDmode similar to the other floating point modes.
+       [SECONDARY_MEMORY_NEEDED]: Treat DDmode similar to DFmode.
+       * config/rs6000/dfp.md (negdd2, absdd2, negtd2, abstd2): New
+       define_expand's.
+       (negdd2_fpr, absdd2_fpr, nabsdd2_fpr, negtd2_fpr, abstd2_fpr,
+       nabstd2_fpr, movdd_hardfloat64_mfpgpr): New define_insn's.
+       (movdd_hardfloat64): Use TARGET_MFPGPR.
+
 2007-04-17  Bernd Schmidt  <bernd.schmidt@analog.com>
 
        * reload1.c (delete_output_reload): Don't count output in n_inherited.
index 28f7b93eef15a8aaa76ca9ce103e2ee5b32980d3..8c78d818f26b6f239888306c84dbd023335e0d5c 100644 (file)
 ;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
 ;; MA 02110-1301, USA.
 
+(define_expand "negdd2"
+  [(set (match_operand:DD 0 "gpc_reg_operand" "")
+       (neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
+  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "")
+
+(define_insn "*negdd2_fpr"
+  [(set (match_operand:DD 0 "gpc_reg_operand" "=f")
+       (neg:DD (match_operand:DD 1 "gpc_reg_operand" "f")))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "fneg %0,%1"
+  [(set_attr "type" "fp")])
+
+(define_expand "absdd2"
+  [(set (match_operand:DD 0 "gpc_reg_operand" "")
+       (abs:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
+  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "")
+
+(define_insn "*absdd2_fpr"
+  [(set (match_operand:DD 0 "gpc_reg_operand" "=f")
+       (abs:DD (match_operand:DD 1 "gpc_reg_operand" "f")))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "fabs %0,%1"
+  [(set_attr "type" "fp")])
+
+(define_insn "*nabsdd2_fpr"
+  [(set (match_operand:DD 0 "gpc_reg_operand" "=f")
+       (neg:DD (abs:DD (match_operand:DF 1 "gpc_reg_operand" "f"))))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "fnabs %0,%1"
+  [(set_attr "type" "fp")])
+
 (define_expand "movdd"
   [(set (match_operand:DD 0 "nonimmediate_operand" "")
        (match_operand:DD 1 "any_operand" ""))]
 
 ; ld/std require word-aligned displacements -> 'Y' constraint.
 ; List Y->r and r->Y before r->r for reload.
+(define_insn "*movdd_hardfloat64_mfpgpr"
+  [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r,r,f")
+       (match_operand:DD 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F,f,r"))]
+  "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
+   && (gpc_reg_operand (operands[0], DDmode)
+       || gpc_reg_operand (operands[1], DDmode))"
+  "@
+   std%U0%X0 %1,%0
+   ld%U1%X1 %0,%1
+   mr %0,%1
+   fmr %0,%1
+   lfd%U1%X1 %0,%1
+   stfd%U0%X0 %1,%0
+   mt%0 %1
+   mf%1 %0
+   {cror 0,0,0|nop}
+   #
+   #
+   #
+   mftgpr %0,%1
+   mffgpr %0,%1"
+  [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr")
+   (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")])
+
+; ld/std require word-aligned displacements -> 'Y' constraint.
+; List Y->r and r->Y before r->r for reload.(define_insn "*movdd_hardfloat64"
 (define_insn "*movdd_hardfloat64"
   [(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r")
        (match_operand:DD 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))]
-  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
+  "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
    && (gpc_reg_operand (operands[0], DDmode)
        || gpc_reg_operand (operands[1], DDmode))"
   "@
   [(set_attr "type" "load,store,*,mtjmpr,mfjmpr,*,*,*,*")
    (set_attr "length" "4,4,4,4,4,8,12,16,4")])
 
+(define_expand "negtd2"
+  [(set (match_operand:TD 0 "gpc_reg_operand" "")
+       (neg:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
+  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "")
+
+(define_insn "*negtd2_fpr"
+  [(set (match_operand:TD 0 "gpc_reg_operand" "=f")
+       (neg:TD (match_operand:TD 1 "gpc_reg_operand" "f")))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "fneg %0,%1"
+  [(set_attr "type" "fp")])
+
+(define_expand "abstd2"
+  [(set (match_operand:TD 0 "gpc_reg_operand" "")
+       (abs:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
+  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
+  "")
+
+(define_insn "*abstd2_fpr"
+  [(set (match_operand:TD 0 "gpc_reg_operand" "=f")
+       (abs:TD (match_operand:TD 1 "gpc_reg_operand" "f")))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "fabs %0,%1"
+  [(set_attr "type" "fp")])
+
+(define_insn "*nabstd2_fpr"
+  [(set (match_operand:TD 0 "gpc_reg_operand" "=f")
+       (neg:TD (abs:TD (match_operand:DF 1 "gpc_reg_operand" "f"))))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "fnabs %0,%1"
+  [(set_attr "type" "fp")])
+
 (define_expand "movtd"
   [(set (match_operand:TD 0 "general_operand" "")
        (match_operand:TD 1 "any_operand" ""))]
index 43ee19e6296b6d44615cecd3048a1d9aa1536878..47e1a910da9f6c199472b46790c57fcd9124a889 100644 (file)
@@ -1134,6 +1134,7 @@ rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
   if (FP_REGNO_P (regno))
     return
       (SCALAR_FLOAT_MODE_P (mode)
+       && (mode != TDmode || (regno % 2) == 0)
        && mode != SDmode
        && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
       || (GET_MODE_CLASS (mode) == MODE_INT
index 8aadc43a16a5443661c5c657c5da5dbb718524a4..57cd68dc2155a896e592e935d92698dd37f325d3 100644 (file)
@@ -590,6 +590,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN)                             \
   (STRICT_ALIGNMENT                                                    \
    || (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode       \
+       || (MODE) == DDmode || (MODE) == TDmode                         \
        || (MODE) == DImode)                                            \
        && (ALIGN) < 32))
 \f
@@ -1147,10 +1148,14 @@ enum reg_class
 #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE)                    \
  ((CLASS1) != (CLASS2) && (((CLASS1) == FLOAT_REGS                     \
                             && (!TARGET_MFPGPR || !TARGET_POWERPC64    \
-                               || ((MODE != DFmode) && (MODE != DImode)))) \
+                               || ((MODE != DFmode)                    \
+                                   && (MODE != DDmode)                 \
+                                   && (MODE != DImode))))              \
                           || ((CLASS2) == FLOAT_REGS                   \
                                && (!TARGET_MFPGPR || !TARGET_POWERPC64 \
-                               || ((MODE != DFmode) && (MODE != DImode)))) \
+                                  || ((MODE != DFmode)                 \
+                                      && (MODE != DDmode)              \
+                                      && (MODE != DImode))))           \
                           || (CLASS1) == ALTIVEC_REGS                  \
                           || (CLASS2) == ALTIVEC_REGS))