OSDN Git Service

* config/rs6000/spe.md (SPE64): New mode macro.
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Nov 2006 16:41:29 +0000 (16:41 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Nov 2006 16:41:29 +0000 (16:41 +0000)
(mov_sidf_e500_subreg0): Change to mov_si<mode>_e500_subreg0.  Add
memory load.
(mov_si<mode>_e500_subreg0_2): New.
(mov_sidf_e500_subreg4): Change to mov_si<mode>_e500_subreg4.  Add
memory load.
(mov_si<mode>_e500_subreg4_2): New.
* config/rs6000/predicates.md (input_operand): Do not allow
invalid E500 subregs.
(rs6000_nonimmediate_operand): Check for invalid E500 subregs also
if TARGET_SPE.
* config/rs6000/rs6000.c (invalid_e500_subreg): Check for subregs
involving DFmode if TARGET_E500_DOUBLE.  Check for subregs
involving vector modes if TARGET_SPE.

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

gcc/ChangeLog
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/spe.md

index 5555cc4..31edafe 100644 (file)
@@ -1,3 +1,20 @@
+2006-11-22  Joseph Myers  <joseph@codesourcery.com>
+
+       * config/rs6000/spe.md (SPE64): New mode macro.
+       (mov_sidf_e500_subreg0): Change to mov_si<mode>_e500_subreg0.  Add
+       memory load.
+       (mov_si<mode>_e500_subreg0_2): New.
+       (mov_sidf_e500_subreg4): Change to mov_si<mode>_e500_subreg4.  Add
+       memory load.
+       (mov_si<mode>_e500_subreg4_2): New.
+       * config/rs6000/predicates.md (input_operand): Do not allow
+       invalid E500 subregs.
+       (rs6000_nonimmediate_operand): Check for invalid E500 subregs also
+       if TARGET_SPE.
+       * config/rs6000/rs6000.c (invalid_e500_subreg): Check for subregs
+       involving DFmode if TARGET_E500_DOUBLE.  Check for subregs
+       involving vector modes if TARGET_SPE.
+
 2006-11-22  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        Revert
index f8e00ff..2ff0ba7 100644 (file)
       && easy_vector_constant (op, mode))
     return 1;
 
+  /* Do not allow invalid E500 subregs.  */
+  if ((TARGET_E500_DOUBLE || TARGET_SPE)
+      && GET_CODE (op) == SUBREG
+      && invalid_e500_subreg (op, mode))
+    return 0;
+
   /* For floating-point or multi-word mode, the only remaining valid type
      is a register.  */
   if (SCALAR_FLOAT_MODE_P (mode)
 (define_predicate "rs6000_nonimmediate_operand"
   (match_code "reg,subreg,mem")
 {
-  if (TARGET_E500_DOUBLE
+  if ((TARGET_E500_DOUBLE || TARGET_SPE)
       && GET_CODE (op) == SUBREG
       && invalid_e500_subreg (op, mode))
     return 0;
index dc80f9f..f8e58fb 100644 (file)
@@ -2713,18 +2713,29 @@ build_mask64_2_operands (rtx in, rtx *out)
 bool
 invalid_e500_subreg (rtx op, enum machine_mode mode)
 {
-  /* Reject (subreg:SI (reg:DF)).  */
-  if (GET_CODE (op) == SUBREG
-      && mode == SImode
-      && REG_P (SUBREG_REG (op))
-      && GET_MODE (SUBREG_REG (op)) == DFmode)
-    return true;
+  if (TARGET_E500_DOUBLE)
+    {
+      /* Reject (subreg:SI (reg:DF)).  */
+      if (GET_CODE (op) == SUBREG
+         && mode == SImode
+         && REG_P (SUBREG_REG (op))
+         && GET_MODE (SUBREG_REG (op)) == DFmode)
+       return true;
 
-  /* Reject (subreg:DF (reg:DI)).  */
-  if (GET_CODE (op) == SUBREG
-      && mode == DFmode
+      /* Reject (subreg:DF (reg:DI)).  */
+      if (GET_CODE (op) == SUBREG
+         && mode == DFmode
+         && REG_P (SUBREG_REG (op))
+         && GET_MODE (SUBREG_REG (op)) == DImode)
+       return true;
+    }
+
+  if (TARGET_SPE
+      && GET_CODE (op) == SUBREG
+      && mode == SImode
       && REG_P (SUBREG_REG (op))
-      && GET_MODE (SUBREG_REG (op)) == DImode)
+      && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op)))
+      && SUBREG_BYTE (op) != 4)
     return true;
 
   return false;
index 02e13c6..7d05e08 100644 (file)
@@ -32,6 +32,9 @@
    (E500_CR_IOR_COMPARE 1012)
    ])
 
+;; Modes using a 64-bit register.
+(define_mode_macro SPE64 [DF V4HI V2SF V1DI V2SI])
+
 (define_insn "*negsf2_gpr"
   [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
         (neg:SF (match_operand:SF 1 "gpc_reg_operand" "r")))]
 }"
   [(set_attr "length" "8,8")])
 
-(define_insn "*mov_sidf_e500_subreg0"
-  [(set (subreg:SI (match_operand:DF 0 "register_operand" "+r") 0)
-       (match_operand:SI 1 "register_operand" "r"))]
-  "TARGET_E500_DOUBLE"
-  "evmergelo %0,%1,%0")
+(define_insn "*mov_si<mode>_e500_subreg0"
+  [(set (subreg:SI (match_operand:SPE64 0 "register_operand" "+r,&r") 0)
+       (match_operand:SI 1 "input_operand" "r,m"))]
+  "(TARGET_E500_DOUBLE && <MODE>mode == DFmode) || (TARGET_SPE && <MODE>mode != DFmode)"
+  "@
+   evmergelo %0,%1,%0
+   evmergelohi %0,%0,%0\;{l%U1%X1|lwz%U1%X1} %0,%1\;evmergelohi %0,%0,%0")
+
+;; ??? Could use evstwwe for memory stores in some cases, depending on
+;; the offset.
+(define_insn "*mov_si<mode>_e500_subreg0_2"
+  [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
+       (subreg:SI (match_operand:SPE64 1 "register_operand" "+r,&r") 0))]
+  "(TARGET_E500_DOUBLE && <MODE>mode == DFmode) || (TARGET_SPE && <MODE>mode != DFmode)"
+  "@
+   evmergehi %0,%0,%1
+   evmergelohi %1,%1,%1\;{st%U0%X0|stw%U0%X0} %1,%0")
 
-(define_insn "*mov_sidf_e500_subreg4"
-  [(set (subreg:SI (match_operand:DF 0 "register_operand" "+r") 4)
-       (match_operand:SI 1 "register_operand" "r"))]
-  "TARGET_E500_DOUBLE"
-  "mr %0,%1")
+(define_insn "*mov_si<mode>_e500_subreg4"
+  [(set (subreg:SI (match_operand:SPE64 0 "register_operand" "+r,r") 4)
+       (match_operand:SI 1 "input_operand" "r,m"))]
+  "(TARGET_E500_DOUBLE && <MODE>mode == DFmode) || (TARGET_SPE && <MODE>mode != DFmode)"
+  "@
+   mr %0,%1
+   {l%U1%X1|lwz%U1%X1} %0,%1")
+
+(define_insn "*mov_si<mode>_e500_subreg4_2"
+  [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
+       (subreg:SI (match_operand:SPE64 1 "register_operand" "r,r") 4))]
+  "(TARGET_E500_DOUBLE && <MODE>mode == DFmode) || (TARGET_SPE && <MODE>mode != DFmode)"
+  "@
+   mr %0,%1
+   {st%U0%X0|stw%U0%X0} %1,%0")
 
 ;; FIXME: Allow r=CONST0.
 (define_insn "*movdf_e500_double"