+2014-06-06 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/61431
+ * config/rs6000/vsx.md (VSX_LE): Split VSX_D into 2 separate
+ iterators, VSX_D that handles 64-bit types, and VSX_LE that
+ handles swapping the two 64-bit double words on little endian
+ systems. Include V1TImode and optionally TImode in VSX_LE so that
+ these types are properly swapped. Change all of the insns and
+ splits that do the 64-bit swaps to use VSX_LE.
+ (vsx_le_perm_load_<mode>): Likewise.
+ (vsx_le_perm_store_<mode>): Likewise.
+ (splitters for little endian memory operations): Likewise.
+ (vsx_xxpermdi2_le_<mode>): Likewise.
+ (vsx_lxvd2x2_le_<mode>): Likewise.
+ (vsx_stxvd2x2_le_<mode>): Likewise.
+
2014-06-06 Uros Bizjak <ubizjak@gmail.com>
PR target/61423
;; Iterator for the 2 64-bit vector types
(define_mode_iterator VSX_D [V2DF V2DI])
+;; Iterator for the 2 64-bit vector types + 128-bit types that are loaded with
+;; lxvd2x to properly handle swapping words on little endian
+(define_mode_iterator VSX_LE [V2DF
+ V2DI
+ V1TI
+ (TI "VECTOR_MEM_VSX_P (TImode)")])
+
;; Iterator for the 2 32-bit vector types
(define_mode_iterator VSX_W [V4SF V4SI])
;; The patterns for LE permuted loads and stores come before the general
;; VSX moves so they match first.
(define_insn_and_split "*vsx_le_perm_load_<mode>"
- [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wa")
- (match_operand:VSX_D 1 "memory_operand" "Z"))]
+ [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=wa")
+ (match_operand:VSX_LE 1 "memory_operand" "Z"))]
"!BYTES_BIG_ENDIAN && TARGET_VSX"
"#"
"!BYTES_BIG_ENDIAN && TARGET_VSX"
(set_attr "length" "8")])
(define_insn "*vsx_le_perm_store_<mode>"
- [(set (match_operand:VSX_D 0 "memory_operand" "=Z")
- (match_operand:VSX_D 1 "vsx_register_operand" "+wa"))]
+ [(set (match_operand:VSX_LE 0 "memory_operand" "=Z")
+ (match_operand:VSX_LE 1 "vsx_register_operand" "+wa"))]
"!BYTES_BIG_ENDIAN && TARGET_VSX"
"#"
[(set_attr "type" "vecstore")
(set_attr "length" "12")])
(define_split
- [(set (match_operand:VSX_D 0 "memory_operand" "")
- (match_operand:VSX_D 1 "vsx_register_operand" ""))]
+ [(set (match_operand:VSX_LE 0 "memory_operand" "")
+ (match_operand:VSX_LE 1 "vsx_register_operand" ""))]
"!BYTES_BIG_ENDIAN && TARGET_VSX && !reload_completed"
[(set (match_dup 2)
(vec_select:<MODE>
;; The post-reload split requires that we re-permute the source
;; register in case it is still live.
(define_split
- [(set (match_operand:VSX_D 0 "memory_operand" "")
- (match_operand:VSX_D 1 "vsx_register_operand" ""))]
+ [(set (match_operand:VSX_LE 0 "memory_operand" "")
+ (match_operand:VSX_LE 1 "vsx_register_operand" ""))]
"!BYTES_BIG_ENDIAN && TARGET_VSX && reload_completed"
[(set (match_dup 1)
(vec_select:<MODE>
;; xxpermdi for little endian loads and stores. We need several of
;; these since the form of the PARALLEL differs by mode.
(define_insn "*vsx_xxpermdi2_le_<mode>"
- [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wa")
- (vec_select:VSX_D
- (match_operand:VSX_D 1 "vsx_register_operand" "wa")
+ [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=wa")
+ (vec_select:VSX_LE
+ (match_operand:VSX_LE 1 "vsx_register_operand" "wa")
(parallel [(const_int 1) (const_int 0)])))]
"!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode)"
"xxpermdi %x0,%x1,%x1,2"
;; lxvd2x for little endian loads. We need several of
;; these since the form of the PARALLEL differs by mode.
(define_insn "*vsx_lxvd2x2_le_<mode>"
- [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wa")
- (vec_select:VSX_D
- (match_operand:VSX_D 1 "memory_operand" "Z")
+ [(set (match_operand:VSX_LE 0 "vsx_register_operand" "=wa")
+ (vec_select:VSX_LE
+ (match_operand:VSX_LE 1 "memory_operand" "Z")
(parallel [(const_int 1) (const_int 0)])))]
"!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode)"
"lxvd2x %x0,%y1"
;; stxvd2x for little endian stores. We need several of
;; these since the form of the PARALLEL differs by mode.
(define_insn "*vsx_stxvd2x2_le_<mode>"
- [(set (match_operand:VSX_D 0 "memory_operand" "=Z")
- (vec_select:VSX_D
- (match_operand:VSX_D 1 "vsx_register_operand" "wa")
+ [(set (match_operand:VSX_LE 0 "memory_operand" "=Z")
+ (vec_select:VSX_LE
+ (match_operand:VSX_LE 1 "vsx_register_operand" "wa")
(parallel [(const_int 1) (const_int 0)])))]
"!BYTES_BIG_ENDIAN && VECTOR_MEM_VSX_P (<MODE>mode)"
"stxvd2x %x1,%y0"