UNSPEC_XXEVAL
UNSPEC_VSTRIR
UNSPEC_VSTRIL
- UNSPEC_EXTRACTL
- UNSPEC_EXTRACTR
])
(define_c_enum "unspecv"
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
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_POWER10"
-{
- 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_POWER10"
- "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_POWER10"
-{
- 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_POWER10"
- "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")]
UNSPEC_VCNTMB
UNSPEC_VEXPAND
UNSPEC_VEXTRACT
+ UNSPEC_EXTRACTL
+ UNSPEC_EXTRACTR
])
(define_int_iterator XVCVBF16 [UNSPEC_VSX_XVCVSPBF16
(define_int_attr xvcvbf16 [(UNSPEC_VSX_XVCVSPBF16 "xvcvspbf16")
(UNSPEC_VSX_XVCVBF16SP "xvcvbf16sp")])
+;; 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
}
[(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_POWER10"
+{
+ 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_POWER10"
+ "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_POWER10"
+{
+ 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_POWER10"
+ "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
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)
@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 @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
-@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 @code{vextdubvrx},
+@code{vextduhvrx}, @code{vextduwvrx} instruction will be generated, while for
+big-endian, semantics matching the @code{vextdubvlx}, @code{vextduhvlx},
+@code{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 @code{vec_perm}.
@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
-@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
-@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. The index is based on big endian order for a little endian system.
+Similarly, the index is based on little endian order for a big endian system.
+The extraced elements are zero-extended and put 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 (vextdubvrx, vextduhvrx,
+vextduwvrx, vextddvrx) 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 @code{vextdubvlx}, @code{vextduhvlx}, @code{vextduwvlx}
+instructions will be generated, while for big-endian, semantics matching the
+@code{vextdubvrx}, @code{vextduhvrx}, @code{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 @code{vec_perm}.
+@findex vec_extracth
@smallexample
@exdent vector unsigned long long int
@exdent vec_pdep (vector unsigned long long int, vector unsigned long long int)