@@ -171,8 +171,6 @@
UNSPEC_XXEVAL
UNSPEC_VSTRIR
UNSPEC_VSTRIL
- UNSPEC_EXTRACTL
- UNSPEC_EXTRACTR
])
(define_c_enum "unspecv"
@@ -183,8 +181,6 @@
UNSPECV_DSS
])
-;; Like VI, defined in vector.md, but add ISA 2.07 integer vector ops
-(define_mode_iterator VI2 [V4SI V8HI V16QI V2DI])
;; Short vec int modes
(define_mode_iterator VIshort [V8HI V16QI])
;; Longer vec int modes for rotate/mask ops
@@ -785,66 +781,6 @@
DONE;
})
-(define_expand "vextractl<mode>"
- [(set (match_operand:V2DI 0 "altivec_register_operand")
- (unspec:V2DI [(match_operand:VI2 1 "altivec_register_operand")
- (match_operand:VI2 2 "altivec_register_operand")
- (match_operand:SI 3 "register_operand")]
- UNSPEC_EXTRACTL))]
- "TARGET_FUTURE"
-{
- if (BYTES_BIG_ENDIAN)
- {
- emit_insn (gen_vextractl<mode>_internal (operands[0], operands[1],
- operands[2], operands[3]));
- emit_insn (gen_xxswapd_v2di (operands[0], operands[0]));
- }
- else
- emit_insn (gen_vextractr<mode>_internal (operands[0], operands[2],
- operands[1], operands[3]));
- DONE;
-})
-
-(define_insn "vextractl<mode>_internal"
- [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
- (unspec:V2DI [(match_operand:VEC_I 1 "altivec_register_operand" "v")
- (match_operand:VEC_I 2 "altivec_register_operand" "v")
- (match_operand:SI 3 "register_operand" "r")]
- UNSPEC_EXTRACTL))]
- "TARGET_FUTURE"
- "vext<du_or_d><wd>vlx %0,%1,%2,%3"
- [(set_attr "type" "vecsimple")])
-
-(define_expand "vextractr<mode>"
- [(set (match_operand:V2DI 0 "altivec_register_operand")
- (unspec:V2DI [(match_operand:VI2 1 "altivec_register_operand")
- (match_operand:VI2 2 "altivec_register_operand")
- (match_operand:SI 3 "register_operand")]
- UNSPEC_EXTRACTR))]
- "TARGET_FUTURE"
-{
- if (BYTES_BIG_ENDIAN)
- {
- emit_insn (gen_vextractr<mode>_internal (operands[0], operands[1],
- operands[2], operands[3]));
- emit_insn (gen_xxswapd_v2di (operands[0], operands[0]));
- }
- else
- emit_insn (gen_vextractl<mode>_internal (operands[0], operands[2],
- operands[1], operands[3]));
- DONE;
-})
-
-(define_insn "vextractr<mode>_internal"
- [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
- (unspec:V2DI [(match_operand:VEC_I 1 "altivec_register_operand" "v")
- (match_operand:VEC_I 2 "altivec_register_operand" "v")
- (match_operand:SI 3 "register_operand" "r")]
- UNSPEC_EXTRACTR))]
- "TARGET_FUTURE"
- "vext<du_or_d><wd>vrx %0,%1,%2,%3"
- [(set_attr "type" "vecsimple")])
-
(define_expand "vstrir_<mode>"
[(set (match_operand:VIshort 0 "altivec_register_operand")
(unspec:VIshort [(match_operand:VIshort 1 "altivec_register_operand")]
@@ -344,8 +344,13 @@
UNSPEC_VSX_FIRST_MISMATCH_INDEX
UNSPEC_VSX_FIRST_MISMATCH_EOS_INDEX
UNSPEC_XXGENPCV
+ UNSPEC_EXTRACTL
+ UNSPEC_EXTRACTR
])
+;; Like VI, defined in vector.md, but add ISA 2.07 integer vector ops
+(define_mode_iterator VI2 [V4SI V8HI V16QI V2DI])
+
;; VSX moves
;; The patterns for LE permuted loads and stores come before the general
@@ -3781,6 +3786,67 @@
}
[(set_attr "type" "load")])
+;; ISA 3.1 extract
+(define_expand "vextractl<mode>"
+ [(set (match_operand:V2DI 0 "altivec_register_operand")
+ (unspec:V2DI [(match_operand:VI2 1 "altivec_register_operand")
+ (match_operand:VI2 2 "altivec_register_operand")
+ (match_operand:SI 3 "register_operand")]
+ UNSPEC_EXTRACTL))]
+ "TARGET_FUTURE"
+{
+ if (BYTES_BIG_ENDIAN)
+ {
+ emit_insn (gen_vextractl<mode>_internal (operands[0], operands[1],
+ operands[2], operands[3]));
+ emit_insn (gen_xxswapd_v2di (operands[0], operands[0]));
+ }
+ else
+ emit_insn (gen_vextractr<mode>_internal (operands[0], operands[2],
+ operands[1], operands[3]));
+ DONE;
+})
+
+(define_insn "vextractl<mode>_internal"
+ [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
+ (unspec:V2DI [(match_operand:VEC_I 1 "altivec_register_operand" "v")
+ (match_operand:VEC_I 2 "altivec_register_operand" "v")
+ (match_operand:SI 3 "register_operand" "r")]
+ UNSPEC_EXTRACTL))]
+ "TARGET_FUTURE"
+ "vext<du_or_d><wd>vlx %0,%1,%2,%3"
+ [(set_attr "type" "vecsimple")])
+
+(define_expand "vextractr<mode>"
+ [(set (match_operand:V2DI 0 "altivec_register_operand")
+ (unspec:V2DI [(match_operand:VI2 1 "altivec_register_operand")
+ (match_operand:VI2 2 "altivec_register_operand")
+ (match_operand:SI 3 "register_operand")]
+ UNSPEC_EXTRACTR))]
+ "TARGET_FUTURE"
+{
+ if (BYTES_BIG_ENDIAN)
+ {
+ emit_insn (gen_vextractr<mode>_internal (operands[0], operands[1],
+ operands[2], operands[3]));
+ emit_insn (gen_xxswapd_v2di (operands[0], operands[0]));
+ }
+ else
+ emit_insn (gen_vextractl<mode>_internal (operands[0], operands[2],
+ operands[1], operands[3]));
+ DONE;
+})
+
+(define_insn "vextractr<mode>_internal"
+ [(set (match_operand:V2DI 0 "altivec_register_operand" "=v")
+ (unspec:V2DI [(match_operand:VEC_I 1 "altivec_register_operand" "v")
+ (match_operand:VEC_I 2 "altivec_register_operand" "v")
+ (match_operand:SI 3 "register_operand" "r")]
+ UNSPEC_EXTRACTR))]
+ "TARGET_FUTURE"
+ "vext<du_or_d><wd>vrx %0,%1,%2,%3"
+ [(set_attr "type" "vecsimple")])
+
;; VSX_EXTRACT optimizations
;; Optimize double d = (double) vec_extract (vi, <n>)
;; Get the element into the top position and use XVCVSWDP/XVCVUWDP
@@ -20919,6 +20919,9 @@ Perform a 128-bit vector gather operation, as if implemented by the Future
integer value between 2 and 7 inclusive.
@findex vec_gnb
+
+Vector Extract
+
@smallexample
@exdent vector unsigned long long int
@exdent vec_extractl (vector unsigned char, vector unsigned char, unsigned int)
@@ -20929,51 +20932,49 @@ integer value between 2 and 7 inclusive.
@exdent vector unsigned long long int
@exdent vec_extractl (vector unsigned long long, vector unsigned long long, unsigned int)
@end smallexample
-Extract a single element from the vector formed by catenating this function's
-first two arguments at the byte offset specified by this function's
-third argument. On big-endian targets, this function behaves as if
-implemented by the Future @code{vextdubvlx}, @code{vextduhvlx},
-@code{vextduwvlx}, or @code{vextddvlx} instructions, depending on the
-types of the function's first two arguments. On little-endian
-targets, this function behaves as if implemented by the Future
-@code{vextdubvrx}, @code{vextduhvrx},
-@code{vextduwvrx}, or @code{vextddvrx} instructions.
-The byte offset of the element to be extracted is calculated
-by computing the remainder of dividing the third argument by 32.
-If this reminader value is not a multiple of the vector element size,
-or if its value added to the vector element size exceeds 32, the
-result is undefined.
+Extract an element from two concatenated vectors starting at the given byte index
+in natural-endian order, and place it zero-extended in doubleword 1 of the result
+according to natural element order. If the byte index is out of range for the
+data type, the intrinsic will be rejected.
+For little-endian, this output will match the placement by the hardware
+instruction, i.e., dword[0] in RTL notation. For big-endian, an additional
+instruction is needed to move it from the "left" doubleword to the "right" one.
+For little-endian, semantics matching the vextdubvrx, vextduhvrx,
+vextduwvrx instruction will be generated, while for big-endian, semantics
+matching the vextdubvlx, vextduhvlx, vextduwvlx instructions
+will be generated. Note that some fairly anomalous results can be generated if
+the byte index is not aligned on an element boundary for the element being
+extracted. This is a limitation of the bi-endian vector programming model is
+consistent with the limitation on vec_perm, for example.
@findex vec_extractl
@smallexample
@exdent vector unsigned long long int
-@exdent vec_extractr (vector unsigned char, vector unsigned char, unsigned int)
+@exdent vec_extracth (vector unsigned char, vector unsigned char, unsigned int)
@exdent vector unsigned long long int
-@exdent vec_extractr (vector unsigned short, vector unsigned short, unsigned int)
+@exdent vec_extracth (vector unsigned short, vector unsigned short,
+unsigned int)
@exdent vector unsigned long long int
-@exdent vec_extractr (vector unsigned int, vector unsigned int, unsigned int)
+@exdent vec_extracth (vector unsigned int, vector unsigned int, unsigned int)
@exdent vector unsigned long long int
-@exdent vec_extractr (vector unsigned long long, vector unsigned long long, unsigned int)
-@end smallexample
-Extract a single element from the vector formed by catenating this function's
-first two arguments at the byte offset calculated by subtracting this
-function's third argument from 31. On big-endian targets, this
-function behaves as if
-implemented by the Future
-@code{vextdubvrx}, @code{vextduhvrx},
-@code{vextduwvrx}, or @code{vextddvrx} instructions, depending on the
-types of the function's first two arguments.
-On little-endian
-targets, this function behaves as if implemented by the Future
-@code{vextdubvlx}, @code{vextduhvlx},
-@code{vextduwvlx}, or @code{vextddvlx} instructions.
-The byte offset of the element to be extracted, measured from the
-right end of the catenation of the two vector arguments, is calculated
-by computing the remainder of dividing the third argument by 32.
-If this reminader value is not a multiple of the vector element size,
-or if its value added to the vector element size exceeds 32, the
-result is undefined.
-@findex vec_extractr
+@exdent vec_extracth (vector unsigned long long, vector unsigned long long,
+unsigned int)
+@end smallexample
+Extract an element from two concatenated vectors starting at the given byte
+index in opposite-endian order, and place it zero-extended in doubleword 1
+according to natural element order. If the byte index is out of range for the
+data type, the intrinsic will be rejected. For little-endian, this output
+will match the placement by the hardware instruction, i.e., dword[0] in RTL
+notation. For big-endian, an additional instruction is needed to move it
+from the "left" doubleword to the "right" one. For little-endian, semantics
+matching the vextdubvlx, vextduhvlx, vextduwvlx instructions will be generated,
+while for big-endian, semantics matching the vextdubvrx, vextduhvrx,
+vextduwvrx instructions will be generated. Note that some fairly anomalous
+results can be generated if the byte index is not aligned on the
+element boundary for the element being extracted. This is a
+limitation of the bi-endian vector programming model consistent with the
+limitation on vec_perm, for example.
+@findex vec_extracth
@smallexample
@exdent vector unsigned long long int