gcc-patches@gcc.gnu.org
[Top] [All Lists]

[PATCH, committed] More Altivec fixes

Subject: [PATCH, committed] More Altivec fixes
From: David Edelsohn
Date: Thu, 11 Aug 2005 17:34:07 -0400
        The earlier Altivec patch exposed some more problems in Altivec
address handling.  The port previously was relying on the generic
legitimate_address machinery to prevent offset addresses, but offset
addresses are necessary and correct for non-strict addresses (before
reload).

        Because output templates and reload now can encouter offset
addresses, the constraints for the patterns need to enforce indexed and
indirect addresses in Altivec forms, and reload needs to know how to
convert addresses wrapped in AND for alignment.

        This patch updates the constraints on the patterns, the predicate
used by the constraint, and adds a way to legitimize offset addresses
wrapped by AND.

Thanks to Eric Christopher for regression testing on powerpc-darwin.

David


        * config/rs6000/altivec.md: Change constraint "m" to "Z".
        * config/rs6000/predicates.md (indexed_or_indirect_operand):
        Accept address wrapped in AND for Altivec.
        * config/rs6000/rs6000.c (rs6000_legitimize_reload_address):
        Strip AND wrapping offset address for Altivec.

Index: altivec.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/altivec.md,v
retrieving revision 1.42
diff -c -p -r1.42 altivec.md
*** altivec.md  8 Aug 2005 16:36:19 -0000       1.42
--- altivec.md  11 Aug 2005 15:08:37 -0000
***************
*** 149,162 ****
  ;; Generic LVX load instruction.
  (define_insn "altivec_lvx_<mode>"
    [(set (match_operand:V 0 "altivec_register_operand" "=v")
!       (match_operand:V 1 "memory_operand" "m"))]
    "TARGET_ALTIVEC"
    "lvx %0,%y1"
    [(set_attr "type" "vecload")])
  
  ;; Generic STVX store instruction.
  (define_insn "altivec_stvx_<mode>"
!   [(set (match_operand:V 0 "memory_operand" "=m")
        (match_operand:V 1 "altivec_register_operand" "v"))]
    "TARGET_ALTIVEC"
    "stvx %1,%y0"
--- 149,162 ----
  ;; Generic LVX load instruction.
  (define_insn "altivec_lvx_<mode>"
    [(set (match_operand:V 0 "altivec_register_operand" "=v")
!       (match_operand:V 1 "memory_operand" "Z"))]
    "TARGET_ALTIVEC"
    "lvx %0,%y1"
    [(set_attr "type" "vecload")])
  
  ;; Generic STVX store instruction.
  (define_insn "altivec_stvx_<mode>"
!   [(set (match_operand:V 0 "memory_operand" "=Z")
        (match_operand:V 1 "altivec_register_operand" "v"))]
    "TARGET_ALTIVEC"
    "stvx %1,%y0"
***************
*** 173,180 ****
  })
  
  (define_insn "*mov<mode>_internal"
!   [(set (match_operand:V 0 "nonimmediate_operand" "=m,v,v,o,r,r,v")
!       (match_operand:V 1 "input_operand" "v,m,v,r,o,r,W"))]
    "TARGET_ALTIVEC 
     && (register_operand (operands[0], <MODE>mode) 
         || register_operand (operands[1], <MODE>mode))"
--- 173,180 ----
  })
  
  (define_insn "*mov<mode>_internal"
!   [(set (match_operand:V 0 "nonimmediate_operand" "=Z,v,v,o,r,r,v")
!       (match_operand:V 1 "input_operand" "v,Z,v,r,o,r,W"))]
    "TARGET_ALTIVEC 
     && (register_operand (operands[0], <MODE>mode) 
         || register_operand (operands[1], <MODE>mode))"
***************
*** 1802,1822 ****
  
  (define_insn "altivec_lvsl"
    [(set (match_operand:V16QI 0 "register_operand" "=v")
!       (unspec:V16QI [(match_operand 1 "memory_operand" "m")] UNSPEC_LVSL))]
    "TARGET_ALTIVEC"
    "lvsl %0,%y1"
    [(set_attr "type" "vecload")])
  
  (define_insn "altivec_lvsr"
    [(set (match_operand:V16QI 0 "register_operand" "=v")
!       (unspec:V16QI [(match_operand 1 "memory_operand" "m")] UNSPEC_LVSR))]
    "TARGET_ALTIVEC"
    "lvsr %0,%y1"
    [(set_attr "type" "vecload")])
  
  (define_expand "build_vector_mask_for_load"
!   [(set (match_operand:V16QI 0 "register_operand" "=v")
!       (unspec:V16QI [(match_operand 1 "memory_operand" "m")] UNSPEC_LVSR))]
    "TARGET_ALTIVEC"
    "
  { 
--- 1802,1822 ----
  
  (define_insn "altivec_lvsl"
    [(set (match_operand:V16QI 0 "register_operand" "=v")
!       (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSL))]
    "TARGET_ALTIVEC"
    "lvsl %0,%y1"
    [(set_attr "type" "vecload")])
  
  (define_insn "altivec_lvsr"
    [(set (match_operand:V16QI 0 "register_operand" "=v")
!       (unspec:V16QI [(match_operand 1 "memory_operand" "Z")] UNSPEC_LVSR))]
    "TARGET_ALTIVEC"
    "lvsr %0,%y1"
    [(set_attr "type" "vecload")])
  
  (define_expand "build_vector_mask_for_load"
!   [(set (match_operand:V16QI 0 "register_operand" "")
!       (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_LVSR))]
    "TARGET_ALTIVEC"
    "
  { 
***************
*** 1858,1864 ****
  (define_insn "altivec_lvxl"
    [(parallel
      [(set (match_operand:V4SI 0 "register_operand" "=v")
!         (match_operand:V4SI 1 "memory_operand" "m"))
       (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
    "TARGET_ALTIVEC"
    "lvxl %0,%y1"
--- 1858,1864 ----
  (define_insn "altivec_lvxl"
    [(parallel
      [(set (match_operand:V4SI 0 "register_operand" "=v")
!         (match_operand:V4SI 1 "memory_operand" "Z"))
       (unspec [(const_int 0)] UNSPEC_SET_VSCR)])]
    "TARGET_ALTIVEC"
    "lvxl %0,%y1"
***************
*** 1866,1879 ****
  
  (define_insn "altivec_lvx"
    [(set (match_operand:V4SI 0 "register_operand" "=v")
!       (match_operand:V4SI 1 "memory_operand" "m"))]
    "TARGET_ALTIVEC"
    "lvx %0,%y1"
    [(set_attr "type" "vecload")])
  
  (define_insn "altivec_stvx"
    [(parallel
!     [(set (match_operand:V4SI 0 "memory_operand" "=m")
          (match_operand:V4SI 1 "register_operand" "v"))
       (unspec [(const_int 0)] UNSPEC_STVX)])]
    "TARGET_ALTIVEC"
--- 1866,1879 ----
  
  (define_insn "altivec_lvx"
    [(set (match_operand:V4SI 0 "register_operand" "=v")
!       (match_operand:V4SI 1 "memory_operand" "Z"))]
    "TARGET_ALTIVEC"
    "lvx %0,%y1"
    [(set_attr "type" "vecload")])
  
  (define_insn "altivec_stvx"
    [(parallel
!     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
          (match_operand:V4SI 1 "register_operand" "v"))
       (unspec [(const_int 0)] UNSPEC_STVX)])]
    "TARGET_ALTIVEC"
***************
*** 1882,1888 ****
  
  (define_insn "altivec_stvxl"
    [(parallel
!     [(set (match_operand:V4SI 0 "memory_operand" "=m")
          (match_operand:V4SI 1 "register_operand" "v"))
       (unspec [(const_int 0)] UNSPEC_STVXL)])]
    "TARGET_ALTIVEC"
--- 1882,1888 ----
  
  (define_insn "altivec_stvxl"
    [(parallel
!     [(set (match_operand:V4SI 0 "memory_operand" "=Z")
          (match_operand:V4SI 1 "register_operand" "v"))
       (unspec [(const_int 0)] UNSPEC_STVXL)])]
    "TARGET_ALTIVEC"
***************
*** 1891,1897 ****
  
  (define_insn "altivec_stve<VI_char>x"
    [(parallel
!     [(set (match_operand:VI 0 "memory_operand" "=m")
          (match_operand:VI 1 "register_operand" "v"))
       (unspec [(const_int 0)] UNSPEC_STVE)])]
    "TARGET_ALTIVEC"
--- 1891,1897 ----
  
  (define_insn "altivec_stve<VI_char>x"
    [(parallel
!     [(set (match_operand:VI 0 "memory_operand" "=Z")
          (match_operand:VI 1 "register_operand" "v"))
       (unspec [(const_int 0)] UNSPEC_STVE)])]
    "TARGET_ALTIVEC"
***************
*** 1900,1906 ****
  
  (define_insn "*altivec_stvesfx"
    [(parallel
!     [(set (match_operand:V4SF 0 "memory_operand" "=m")
          (match_operand:V4SF 1 "register_operand" "v"))
       (unspec [(const_int 0)] UNSPEC_STVE)])]
    "TARGET_ALTIVEC"
--- 1900,1906 ----
  
  (define_insn "*altivec_stvesfx"
    [(parallel
!     [(set (match_operand:V4SF 0 "memory_operand" "=Z")
          (match_operand:V4SF 1 "register_operand" "v"))
       (unspec [(const_int 0)] UNSPEC_STVE)])]
    "TARGET_ALTIVEC"
Index: predicates.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/predicates.md,v
retrieving revision 1.22
diff -c -p -r1.22 predicates.md
*** predicates.md       10 Aug 2005 14:21:52 -0000      1.22
--- predicates.md       11 Aug 2005 15:08:37 -0000
***************
*** 355,365 ****
  
  ;; Return 1 if the operand is an indexed or indirect memory operand.
  (define_predicate "indexed_or_indirect_operand"
!   (and (match_operand 0 "memory_operand")
!        (match_test "REG_P (XEXP (op, 0))
!                   || (GET_CODE (XEXP (op, 0)) == PLUS
!                       && REG_P (XEXP (XEXP (op, 0), 0)) 
!                       && REG_P (XEXP (XEXP (op, 0), 1)))")))
  
  ;; Return 1 if the operand is a memory operand with an address divisible by 4
  (define_predicate "word_offset_memref_operand"
--- 355,376 ----
  
  ;; Return 1 if the operand is an indexed or indirect memory operand.
  (define_predicate "indexed_or_indirect_operand"
!   (match_operand 0 "memory_operand")
! {
!   rtx tmp = XEXP (op, 0);
! 
!   if (TARGET_ALTIVEC
!       && ALTIVEC_VECTOR_MODE (mode)
!       && GET_CODE (tmp) == AND
!       && GET_CODE (XEXP (tmp, 1)) == CONST_INT
!       && INTVAL (XEXP (tmp, 1)) == -16)
!     tmp = XEXP (tmp, 0);
! 
!     return REG_P (tmp)
!                 || (GET_CODE (tmp) == PLUS
!                     && REG_P (XEXP (tmp, 0)) 
!                     && REG_P (XEXP (tmp, 1)));
! })
  
  ;; Return 1 if the operand is a memory operand with an address divisible by 4
  (define_predicate "word_offset_memref_operand"
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.859
diff -c -p -r1.859 rs6000.c
*** rs6000.c    10 Aug 2005 19:52:52 -0000      1.859
--- rs6000.c    11 Aug 2005 15:08:38 -0000
*************** rs6000_legitimize_reload_address (rtx x,
*** 3332,3337 ****
--- 3332,3354 ----
      }
  #endif
  
+   /* Reload an offset address wrapped by an AND that represents the
+      masking of the lower bits.  Strip the outer AND and let reload
+      convert the offset address into an indirect address.  */
+   if (TARGET_ALTIVEC
+       && ALTIVEC_VECTOR_MODE (mode)
+       && GET_CODE (x) == AND
+       && GET_CODE (XEXP (x, 0)) == PLUS
+       && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+       && GET_CODE (XEXP (x, 1)) == CONST_INT
+       && INTVAL (XEXP (x, 1)) == -16)
+     {
+       x = XEXP (x, 0);
+       *win = 1;
+       return x;
+     }
+ 
    if (TARGET_TOC
        && constant_pool_expr_p (x)
        && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH, committed] More Altivec fixes, David Edelsohn <=