Hello, Below patch is bootstrapped and regtested on powerpc64*-linux-gnu with no regressions.
This patch depends on: https://www.mail-archive.com/[email protected]/msg407092.html for future-vsx stanza support and should be committed after the patch is commited. Changes from v3: - Tested on both little-endian and big-endian targets. - Added documentation and explanatory comments. - Reorganized builtins into future-vsx and future-altivec stanzas. - Fixed mode mismatches in builtin definitions and md patterns of altivec_vupkint4tobf16 and altivec_vupkint8tobf16. - Updated and corrected testcases as requested during review. Changes from v2: - Add endian compensation sequence for LE so that the logical vector element ordering matches BE semantics. Changes from v1: - Add missing author line: 2025-03-11 Kishan Parmar <[email protected]> Thank you, Kishan Add support for vector uncompress and unpack instructions proposed in RFC02691. These instructions may or may not be added to a future Power processor, and the names of the builtins may change in the future. The instructions are exposed through new builtins and intrinsics interfaces and are enabled when compiling with -mcpu=future. This patch adds RTL patterns for vector uncompress (nibble, byte, and halfword) and unpack operations in altivec.md, along with the corresponding builtin definitions in rs6000-builtins.def and overload entries in rs6000-overload.def. The following new builtins are provided: vector unsigned short vec_uncompresshn (vector unsigned char, vector unsigned int) vector unsigned int vec_uncompresshb (vector unsigned short, vector unsigned short) vector unsigned long long vec_uncompresshh (vector unsigned int, vector unsigned char) vector unsigned short vec_uncompressln (vector unsigned char, vector unsigned int) vector unsigned int vec_uncompresslb (vector unsigned short, vector unsigned short) vector unsigned long long vec_uncompresslh (vector unsigned int, vector unsigned char) vector signed char vec_unpack_hsn_to_byte (vector unsigned long long) vector signed char vec_unpack_lsn_to_byte (vector unsigned long long) vector unsigned char vec_unpack_int4_to_bf16 (vector unsigned short, const int<2>) vector unsigned char vec_unpack_int8_to_bf16 (vector unsigned short, const int<1>) vector float vec_unpack_int4_to_fp32 (vector unsigned int, const int<3>) vector float vec_unpack_int8_to_fp32 (vector unsigned int, const int<2>) 2026-06-23 Kishan Parmar <[email protected]> gcc/ChangeLog: * config/rs6000/altivec.md (UNSPEC_VUCMPRHN): New unspec entry. (UNSPEC_VUCMPRLN): Likewise. (UNSPEC_VUCMPRHB): Likewise. (UNSPEC_VUCMPRLB): Likewise. (UNSPEC_VUCMPRHH): Likewise. (UNSPEC_VUCMPRLH): Likewise. (UNSPEC_VUPKHSNTOB): Likewise. (UNSPEC_VUPKLSNTOB): Likewise. (UNSPEC_VUPKINT4TOBF16): Likewise. (UNSPEC_VUPKINT8TOBF16): Likewise. (UNSPEC_VUPKINT4TOFP32): Likewise. (UNSPEC_VUPKINT8TOFP32): Likewise. (vu_hl): New attribute. (vu_lh): Likewise. (VUPKNTOB): New int iterator. (altivec_vupkhsntob): New define_insn. (altivec_vupklsntob): Likewise. (altivec_vupkint4tobf16): Likewise. (altivec_vupkint8tobf16): Likewise. (altivec_vupkint4tofp32): Likewise. (altivec_vupkint8tofp32): Likewise. (vucmpr_splat): New attribute. (vucmpr_pcv): Likewise. (vucmpr_uim): Likewise. (VUCMPR_N): New int iterator. (VUCMPR_B): Likewise. (VUCMPR_H): Likewise. (altivec_vucmpr<vu_hl>n): New define_expand. (altivec_vucmpr<vu_hl>n_direct): New define_insn for vucmpr<vu_hl>n. (altivec_vucmpr<vu_hl>b): New define_expand. (altivec_vucmpr<vu_hl>b_direct): New define_insn for vucmpr<vu_hl>b. (altivec_vucmpr<vu_hl>h): New define_expand. (altivec_vucmpr<vu_hl>h_direct): New define_insn for vucmpr<vu_hl>h. * config/rs6000/rs6000-builtins.def: Add vector uncompress and unpack builtins under [future]. * config/rs6000/rs6000-overload.def: Add vec_uncompress* and vec_unpack* interfaces. gcc/testsuite/ChangeLog: * gcc/testsuite/gcc.target/powerpc/future-vucmpr-altivec.c: New test. * gcc/testsuite/gcc.target/powerpc/future-vucmpr-vsx.c: Likewise. * gcc/testsuite/gcc.target/powerpc/future-vupk.c: Likewise. --- gcc/config/rs6000/altivec.md | 362 ++++++++++++++++++ gcc/config/rs6000/rs6000-builtins.def | 37 ++ gcc/config/rs6000/rs6000-overload.def | 47 +++ .../powerpc/future-vucmpr-altivec.c | 50 +++ .../gcc.target/powerpc/future-vucmpr-vsx.c | 61 +++ .../gcc.target/powerpc/future-vupk.c | 51 +++ 6 files changed, 608 insertions(+) create mode 100644 gcc/testsuite/gcc.target/powerpc/future-vucmpr-altivec.c create mode 100644 gcc/testsuite/gcc.target/powerpc/future-vucmpr-vsx.c create mode 100644 gcc/testsuite/gcc.target/powerpc/future-vupk.c diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 129f56245cd..32a6d3f3eb4 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -171,6 +171,18 @@ UNSPEC_SLDB UNSPEC_SRDB UNSPEC_VECTOR_SHIFT + UNSPEC_VUCMPRHN + UNSPEC_VUCMPRLN + UNSPEC_VUCMPRHB + UNSPEC_VUCMPRLB + UNSPEC_VUCMPRHH + UNSPEC_VUCMPRLH + UNSPEC_VUPKHSNTOB + UNSPEC_VUPKLSNTOB + UNSPEC_VUPKINT4TOBF16 + UNSPEC_VUPKINT8TOBF16 + UNSPEC_VUPKINT4TOFP32 + UNSPEC_VUPKINT8TOFP32 ]) (define_c_enum "unspecv" @@ -4826,3 +4838,353 @@ (match_dup 3)] UNSPEC_BCD_ADD_SUB) (match_dup 4)))])]) + +(define_int_attr vu_hl [(UNSPEC_VUPKHSNTOB "h") (UNSPEC_VUPKLSNTOB "l") + (UNSPEC_VUCMPRHN "h") (UNSPEC_VUCMPRLN "l") + (UNSPEC_VUCMPRHB "h") (UNSPEC_VUCMPRLB "l") + (UNSPEC_VUCMPRHH "h") (UNSPEC_VUCMPRLH "l")]) + +(define_int_attr vu_lh [(UNSPEC_VUPKHSNTOB "l") (UNSPEC_VUPKLSNTOB "h") + (UNSPEC_VUCMPRHN "l") (UNSPEC_VUCMPRLN "h") + (UNSPEC_VUCMPRHB "l") (UNSPEC_VUCMPRLB "h") + (UNSPEC_VUCMPRHH "l") (UNSPEC_VUCMPRLH "h")]) + +;; Vector unpack instructions for future. + +(define_int_iterator VUPKNTOB [UNSPEC_VUPKHSNTOB UNSPEC_VUPKLSNTOB]) + +(define_insn "altivec_vupk<vu_hl>sntob_direct" + [(set (match_operand:V16QI 0 "altivec_register_operand" "=v") + (unspec:V16QI [(match_operand:V2DI 1 "altivec_register_operand" "v")] + VUPKNTOB))] + "TARGET_FUTURE && TARGET_VSX" + "vupk<vu_hl>sntob %0, %1" + [(set_attr "type" "vecperm")]) + +;; Unpack signed nibbles to bytes. +;; For big-endian, generates: +;; vupk<vu_hl>sntob operands[0], operands[1] +;; For little-endian, generates (requires VSX for xxbrq): +;; vupk<vu_lh>sntob operands[0], operands[1] +;; xxbrq operands[0], operands[0] +;; TARGET_VSX is required because the builtin operates on V2DI (vector +;; unsigned long long), which requires -mvsx. On little-endian systems, +;; the endian compensation also uses the VSX xxbrq instruction. + +(define_expand "altivec_vupk<vu_hl>sntob" + [(set (match_operand:V16QI 0 "altivec_register_operand") + (unspec:V16QI [(match_operand:V2DI 1 "altivec_register_operand")] + VUPKNTOB))] + "TARGET_FUTURE && TARGET_VSX" +{ + if (BYTES_BIG_ENDIAN) + emit_insn (gen_altivec_vupk<vu_hl>sntob_direct (operands[0], + operands[1])); + else + { + emit_insn (gen_altivec_vupk<vu_lh>sntob_direct (operands[0], + operands[1])); + emit_insn (gen_p9_xxbrq_v16qi (operands[0], operands[0])); + } + DONE; +}) + +(define_insn "altivec_vupkint4tobf16" + [(set (match_operand:V16QI 0 "altivec_register_operand" "=v") + (unspec:V16QI [(match_operand:V8HI 1 "altivec_register_operand" "v") + (match_operand:QI 2 "const_0_to_3_operand" "i")] + UNSPEC_VUPKINT4TOBF16))] + "TARGET_FUTURE" + "vupkint4tobf16 %0, %1, %2" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vupkint8tobf16" + [(set (match_operand:V16QI 0 "altivec_register_operand" "=v") + (unspec:V16QI [(match_operand:V8HI 1 "altivec_register_operand" "v") + (match_operand:QI 2 "const_0_to_1_operand" "i")] + UNSPEC_VUPKINT8TOBF16))] + "TARGET_FUTURE" + "vupkint8tobf16 %0, %1, %2" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vupkint4tofp32" + [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") + (unspec:V4SF [(match_operand:V4SI 1 "altivec_register_operand" "v") + (match_operand:QI 2 "const_0_to_7_operand" "i")] + UNSPEC_VUPKINT4TOFP32))] + "TARGET_FUTURE" + "vupkint4tofp32 %0, %1, %2" + [(set_attr "type" "vecperm")]) + +(define_insn "altivec_vupkint8tofp32" + [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") + (unspec:V4SF [(match_operand:V4SI 1 "altivec_register_operand" "v") + (match_operand:QI 2 "const_0_to_3_operand" "i")] + UNSPEC_VUPKINT8TOFP32))] + "TARGET_FUTURE" + "vupkint8tofp32 %0, %1, %2" + [(set_attr "type" "vecperm")]) + +;; Vector uncompress instructions for future. + +;; VSX splat values for vector uncompress instructions for little endian. +(define_int_attr vucmpr_splat [(UNSPEC_VUCMPRHN "3") + (UNSPEC_VUCMPRLN "2") + (UNSPEC_VUCMPRHB "7") + (UNSPEC_VUCMPRLB "6") + (UNSPEC_VUCMPRHH "15") + (UNSPEC_VUCMPRLH "14")]) + +;; Altivec PCV(Permute Control Vector) mask values for vperm used in +;; little endian. +(define_int_attr vucmpr_pcv [(UNSPEC_VUCMPRHN "0x0f0e0d0c") + (UNSPEC_VUCMPRLN "0x0b0a0908") + (UNSPEC_VUCMPRHB "0x0f0e0000") + (UNSPEC_VUCMPRLB "0x0d0c0000")]) + +;; Values for UIM which are used in vinsw instruction which will be used in +;; little-endian, to know in vector. +(define_int_attr vucmpr_uim [(UNSPEC_VUCMPRHN "4") (UNSPEC_VUCMPRLN "0") + (UNSPEC_VUCMPRHB "2") (UNSPEC_VUCMPRLB "0")]) + +/* On little-endian systems, the selector/mask layout does not match + the architectural element ordering used by the vector uncompress + instructions. Byte-wise reverse the selector layout and swap the high/low + nibbles so that the resulting vector matches big-endian semantics. */ + +;; Vector Uncompress Nibbles + +(define_int_iterator VUCMPR_N [UNSPEC_VUCMPRHN UNSPEC_VUCMPRLN]) + +(define_insn "altivec_vucmpr<vu_hl>n_direct" + [(set (match_operand:V8HI 0 "altivec_register_operand" "=v") + (unspec:V8HI [(match_operand:V16QI 1 "altivec_register_operand" "v") + (match_operand:V4SI 2 "altivec_register_operand" "v")] + VUCMPR_N))] + "TARGET_FUTURE" + "vucmpr<vu_hl>n %0, %1, %2") + +;; Vector uncompress nibbles. +;; For big-endian, generates: +;; vucmpr<vu_hl>n operands[0], operands[1], operands[2] +;; For little-endian with VSX, generates: +;; vspltw splat, operands[2], <vucmpr_splat> +;; xxbrw splat, splat +;; vspltisb shift, 4 +;; vrlb rotated, bytes, shift +;; vucmpr<vu_lh>n operands[0], operands[1], selector +;; For little-endian without VSX (Altivec-only), generates: +;; pli mask, <vucmpr_pcv> +;; vinsw pcv, mask, <vucmpr_uim> +;; vperm operands[2], operands[2], operands[2], perm +;; vspltisb shift, 4 +;; vrlb rotated, bytes, shift +;; vucmpr<vu_lh>n operands[0], operands[1], selector +;; +;; Uncompress builtins require special handling on little-endian systems because +;; the selector/mask layout does not match the architectural element ordering +;; used by the vector uncompress instructions. The selector must be byte-wise +;; reversed and the high/low nibbles swapped (via rotation) so that the +;; resulting vector matches big-endian semantics. + +(define_expand "altivec_vucmpr<vu_hl>n" + [(set (match_operand:V8HI 0 "altivec_register_operand") + (unspec:V8HI [(match_operand:V16QI 1 "altivec_register_operand") + (match_operand:V4SI 2 "altivec_register_operand")] + VUCMPR_N))] + "TARGET_FUTURE" +{ + if (BYTES_BIG_ENDIAN) + { + emit_insn (gen_altivec_vucmpr<vu_hl>n_direct(operands[0], operands[1], + operands[2])); + DONE; + } + if (TARGET_VSX) + { + rtx splat = gen_reg_rtx (V4SImode); + rtx shift = gen_reg_rtx (V16QImode); + rtx bytes = gen_reg_rtx (V16QImode); + rtx rotated = gen_reg_rtx (V16QImode); + rtx selector = gen_reg_rtx (V4SImode); + + emit_insn (gen_altivec_vspltw_direct (splat, operands[2], + GEN_INT (<vucmpr_splat>))); + emit_insn (gen_p9_xxbrw_v4si (splat, splat)); + emit_move_insn (bytes, gen_lowpart (V16QImode, splat)); + emit_insn (gen_altivec_vspltisb (shift, GEN_INT (4))); + emit_insn (gen_altivec_vrlb (rotated, bytes, shift)); + emit_move_insn (selector, gen_lowpart (V4SImode, rotated)); + emit_insn (gen_altivec_vucmpr<vu_lh>n_direct (operands[0], operands[1], + selector)); + } + else + { + rtx pcv = gen_reg_rtx (V4SImode); + rtx perm = gen_reg_rtx (V16QImode); + rtx mask = gen_reg_rtx (SImode); + rtx shift = gen_reg_rtx (V16QImode); + rtx bytes = gen_reg_rtx (V16QImode); + rtx rotated = gen_reg_rtx (V16QImode); + rtx selector = gen_reg_rtx (V4SImode); + + emit_move_insn (mask, GEN_INT (<vucmpr_pcv>)); + emit_insn (gen_vreplace_elt_v4si_inst (pcv, pcv, mask, + GEN_INT (<vucmpr_uim>))); + emit_move_insn (perm, gen_lowpart (V16QImode, pcv)); + emit_insn (gen_altivec_vperm_v4si_direct (operands[2], operands[2], + operands[2], perm)); + emit_insn (gen_altivec_vspltisb (shift, GEN_INT (4))); + emit_move_insn (bytes, gen_lowpart (V16QImode, operands[2])); + emit_insn (gen_altivec_vrlb (rotated, bytes, shift)); + emit_move_insn (selector, gen_lowpart (V4SImode, rotated)); + emit_insn (gen_altivec_vucmpr<vu_lh>n_direct (operands[0], operands[1], + selector)); + } + + DONE; +}) + +;; Vector Uncompress Bytes + +(define_int_iterator VUCMPR_B [UNSPEC_VUCMPRHB UNSPEC_VUCMPRLB]) + +(define_insn "altivec_vucmpr<vu_hl>b_direct" + [(set (match_operand:V4SI 0 "altivec_register_operand" "=v") + (unspec:V4SI [(match_operand:V8HI 1 "altivec_register_operand" "v") + (match_operand:V8HI 2 "altivec_register_operand" "v")] + VUCMPR_B))] + "TARGET_FUTURE" + "vucmpr<vu_hl>b %0, %1, %2" + [(set_attr "type" "vecperm")]) + +;; Vector uncompress bytes. +;; For big-endian, generates: +;; vucmpr<vu_hl>b operands[0], operands[1], operands[2] +;; For little-endian with VSX, generates: +;; vsplth splat, operands[2], <vucmpr_splat> +;; xxbrh splat, splat +;; vspltisb shift, 4 +;; vrlb rotated, bytes, shift +;; vucmpr<vu_lh>b operands[0], operands[1], selector +;; For little-endian without VSX (Altivec-only), generates: +;; pli mask, <vucmpr_pcv> +;; vinsw pcv, mask, <vucmpr_uim> +;; vperm bytes, bytes, bytes, perm +;; vspltisb shift, 4 +;; vrlb rotated, bytes, shift +;; vucmpr<vu_lh>b operands[0], operands[1], selector +;; +;; Below builtins require special handling on little-endian systems similar +;; to nibbles, with selector byte-reversal and nibble swapping via rotation. + +(define_expand "altivec_vucmpr<vu_hl>b" + [(set (match_operand:V4SI 0 "altivec_register_operand") + (unspec:V4SI [(match_operand:V8HI 1 "altivec_register_operand") + (match_operand:V8HI 2 "altivec_register_operand")] + VUCMPR_B))] + "TARGET_FUTURE" +{ + if (BYTES_BIG_ENDIAN) + { + emit_insn (gen_altivec_vucmpr<vu_hl>b_direct (operands[0], operands[1], + operands[2])); + DONE; + } + if (TARGET_VSX) + { + rtx splat = gen_reg_rtx (V8HImode); + rtx shift = gen_reg_rtx (V16QImode); + rtx bytes = gen_reg_rtx (V16QImode); + rtx rotated = gen_reg_rtx (V16QImode); + rtx selector = gen_reg_rtx (V8HImode); + + emit_insn (gen_altivec_vsplth_direct (splat, operands[2], + GEN_INT (<vucmpr_splat>))); + emit_insn (gen_p9_xxbrh_v8hi (splat, splat)); + emit_move_insn (bytes, gen_lowpart (V16QImode, splat)); + emit_insn (gen_altivec_vspltisb (shift, GEN_INT (4))); + emit_insn (gen_altivec_vrlb (rotated, bytes, shift)); + emit_move_insn (selector, gen_lowpart (V8HImode, rotated)); + emit_insn (gen_altivec_vucmpr<vu_lh>b_direct (operands[0], operands[1], + selector)); + } + else + { + rtx pcv = gen_reg_rtx (V4SImode); + rtx perm = gen_reg_rtx (V16QImode); + rtx mask = gen_reg_rtx (SImode); + rtx shift = gen_reg_rtx (V16QImode); + rtx bytes = gen_reg_rtx (V16QImode); + rtx rotated = gen_reg_rtx (V16QImode); + rtx selector = gen_reg_rtx (V8HImode); + + emit_move_insn (mask, GEN_INT (<vucmpr_pcv>)); + emit_insn (gen_vreplace_elt_v4si_inst (pcv, pcv, mask, + GEN_INT (<vucmpr_uim>))); + emit_move_insn (perm, gen_lowpart (V16QImode, pcv)); + emit_move_insn (bytes, gen_lowpart (V16QImode, operands[2])); + emit_insn (gen_altivec_vperm_v16qi_direct (bytes, bytes, bytes, perm)); + emit_insn (gen_altivec_vspltisb (shift, GEN_INT (4))); + emit_insn (gen_altivec_vrlb (rotated, bytes, shift)); + emit_move_insn (selector, gen_lowpart (V8HImode, rotated)); + emit_insn (gen_altivec_vucmpr<vu_lh>b_direct (operands[0], operands[1], + selector)); + } + + DONE; +}) + +;; Vector Uncompress Halfwords + +(define_int_iterator VUCMPR_H [UNSPEC_VUCMPRHH UNSPEC_VUCMPRLH]) + +(define_insn "altivec_vucmpr<vu_hl>h_direct" + [(set (match_operand:V2DI 0 "altivec_register_operand" "=v") + (unspec:V2DI [(match_operand:V4SI 1 "altivec_register_operand" "v") + (match_operand:V16QI 2 "altivec_register_operand" "v")] + VUCMPR_H))] + "TARGET_FUTURE && TARGET_VSX" + "vucmpr<vu_hl>h %0, %1, %2" + [(set_attr "type" "vecperm")]) + +;; Vector uncompress halfwords. +;; For big-endian, generates: +;; vucmpr<vu_hl>h operands[0], operands[1], operands[2] +;; For little-endian, generates: +;; vspltb splat, operands[2], <vucmpr_splat> +;; vspltisb shift, 4 +;; vrlb rotated, splat, shift +;; vucmpr<vu_lh>h operands[0], operands[1], rotated +;; +;; TARGET_VSX is required because the builtin operates on V2DI (vector +;; unsigned long long), which requires -mvsx. + +(define_expand "altivec_vucmpr<vu_hl>h" + [(set (match_operand:V2DI 0 "altivec_register_operand") + (unspec:V2DI [(match_operand:V4SI 1 "altivec_register_operand") + (match_operand:V16QI 2 "altivec_register_operand")] + VUCMPR_H))] + "TARGET_FUTURE && TARGET_VSX" +{ + if (BYTES_BIG_ENDIAN) + { + emit_insn (gen_altivec_vucmpr<vu_hl>h_direct (operands[0], operands[1], + operands[2])); + } + else + { + rtx splat = gen_reg_rtx (V16QImode); + rtx shift = gen_reg_rtx (V16QImode); + rtx rotated = gen_reg_rtx (V16QImode); + + emit_insn (gen_altivec_vspltb_direct (splat, operands[2], + GEN_INT (<vucmpr_splat>))); + emit_insn (gen_altivec_vspltisb (shift, GEN_INT (4))); + emit_insn (gen_altivec_vrlb (rotated, splat, shift)); + emit_insn (gen_altivec_vucmpr<vu_lh>h_direct (operands[0], operands[1], + rotated)); + } + DONE; +}) + diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def index b5b6c98b69e..9222a76f0c4 100644 --- a/gcc/config/rs6000/rs6000-builtins.def +++ b/gcc/config/rs6000/rs6000-builtins.def @@ -3977,3 +3977,40 @@ const vss __builtin_vsx_xvmulhsh (vss, vss); XVMULHSH smulv8hi3_highpart {} + + const vull __builtin_altivec_uncompresshh (vui, vuc); + VUCMPRHH altivec_vucmprhh {} + + const vull __builtin_altivec_uncompresslh (vui, vuc); + VUCMPRLH altivec_vucmprlh {} + + const vsc __builtin_altivec_unpack_hsn_to_byte (vull); + VUPKHSNTOB altivec_vupkhsntob {} + + const vsc __builtin_altivec_unpack_lsn_to_byte (vull); + VUPKLSNTOB altivec_vupklsntob {} + +[future-altivec] + const vus __builtin_altivec_uncompresshn (vuc, vui); + VUCMPRHN altivec_vucmprhn {} + + const vui __builtin_altivec_uncompresshb (vus, vus); + VUCMPRHB altivec_vucmprhb {} + + const vus __builtin_altivec_uncompressln (vuc, vui); + VUCMPRLN altivec_vucmprln {} + + const vui __builtin_altivec_uncompresslb (vus, vus); + VUCMPRLB altivec_vucmprlb {} + + const vuc __builtin_altivec_unpack_int4_to_bf16 (vus, const int<2>); + VUPKINT4TOBF16 altivec_vupkint4tobf16 {} + + const vuc __builtin_altivec_unpack_int8_to_bf16 (vus, const int<1>); + VUPKINT8TOBF16 altivec_vupkint8tobf16 {} + + const vf __builtin_altivec_unpack_int4_to_fp32 (vui, const int<3>); + VUPKINT4TOFP32 altivec_vupkint4tofp32 {} + + const vf __builtin_altivec_unpack_int8_to_fp32 (vui, const int<2>); + VUPKINT8TOFP32 altivec_vupkint8tofp32 {} diff --git a/gcc/config/rs6000/rs6000-overload.def b/gcc/config/rs6000/rs6000-overload.def index ef7b59ed112..11cd29f45c0 100644 --- a/gcc/config/rs6000/rs6000-overload.def +++ b/gcc/config/rs6000/rs6000-overload.def @@ -5015,6 +5015,53 @@ vd __builtin_vsx_xxsldwi (vd, vd, const int); XXSLDWI_2DF XXSLDWI_VD2 +[VEC_UCMPRHN, vec_uncompresshn, __builtin_vec_uncompresshn] + vus __builtin_vec_uncompresshn (vuc, vui); + VUCMPRHN + +[VEC_UCMPRHB, vec_uncompresshb, __builtin_vec_uncomresshb] + vui __builtin_vec_uncomresshb (vus, vus); + VUCMPRHB + +[VEC_UCMPRHH, vec_uncompresshh, __builtin_vec_uncomresshh] + vull __builtin_vec_uncomresshh (vui, vuc); + VUCMPRHH + +[VEC_UCMPRLN, vec_uncompressln, __builtin_vec_uncomressln] + vus __builtin_vec_uncomressln (vuc, vui); + VUCMPRLN + +[VEC_UCMPRLB, vec_uncompresslb, __builtin_vec_uncomresslb] + vui __builtin_vec_uncomresslb (vus, vus); + VUCMPRLB + +[VEC_UCMPRLH, vec_uncompresslh, __builtin_vec_uncomresslh] + vull __builtin_vec_uncomresslh (vui, vuc); + VUCMPRLH + +[VEC_UNPACK_HSN_TO_BYTE, vec_unpack_hsn_to_byte, __builtin_vec_unpack_hsn_to_byte] + vsc __builtin_vec_unpack_hsn_to_byte (vull); + VUPKHSNTOB + +[VEC_UNPACK_LSN_TO_BYTE, vec_unpack_lsn_to_byte, __builtin_vec_unpack_lsn_to_byte] + vsc __builtin_vec_unpack_lsn_to_byte (vull); + VUPKLSNTOB + +[VEC_UNPACK_INT4_TO_BF16, vec_unpack_int4_to_bf16, __builtin_vec_unpack_int4_to_bf16] + vuc __builtin_vec_unpack_int4_to_bf16 (vus, const int<2>); + VUPKINT4TOBF16 + +[VEC_UNPACK_INT8_TO_BF16, vec_unpack_int8_to_bf16, __builtin_vec_unpack_int8_to_bf16] + vuc __builtin_vec_unpack_int8_to_bf16 (vus, const int<1>); + VUPKINT8TOBF16 + +[VEC_UNPACK_INT4_TO_FP32, vec_unpack_int4_to_fp32, __builtin_vec_unpack_int4_to_fp32] + vf __builtin_vec_unpack_int4_to_fp32 (vui, const int<3>); + VUPKINT4TOFP32 + +[VEC_UNPACK_INT8_TO_FP32, vec_unpack_int8_to_fp32, __builtin_vec_unpack_int8_to_fp32] + vf __builtin_vec_unpack_int8_to_fp32 (vui, const int<2>); + VUPKINT8TOFP32 ; ************************************************************************** ; ************************************************************************** diff --git a/gcc/testsuite/gcc.target/powerpc/future-vucmpr-altivec.c b/gcc/testsuite/gcc.target/powerpc/future-vucmpr-altivec.c new file mode 100644 index 00000000000..62f48cc3c67 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/future-vucmpr-altivec.c @@ -0,0 +1,50 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mdejagnu-cpu=future -mno-vsx" } */ +/* { dg-require-effective-target powerpc_future_compile_ok } */ + +#include <altivec.h> + +vector unsigned short +test_uncompresshn (vector unsigned char a, + vector unsigned int b) +{ + return vec_uncompresshn (a, b); +} + +vector unsigned int +test_uncompresshb (vector unsigned short a, + vector unsigned short b) +{ + return vec_uncompresshb (a, b); +} + +vector unsigned short +test_uncompressln (vector unsigned char a, + vector unsigned int b) +{ + return vec_uncompressln (a, b); +} + +vector unsigned int +test_uncompresslb (vector unsigned short a, + vector unsigned short b) +{ + return vec_uncompresslb (a, b); +} + +/* { dg-final { scan-assembler-not "vxor" { target { be } } } } */ +/* { dg-final { scan-assembler-not "vinsw" { target { be } } } } */ +/* { dg-final { scan-assembler-not "vperm" { target { be } } } } */ + + +/* { dg-final { scan-assembler-times "vxor" 4 { target { le } } } } */ +/* { dg-final { scan-assembler-times "vinsw" 4 { target { le } } } } */ +/* { dg-final { scan-assembler-times "vperm" 4 { target { le } } } } */ +/* { dg-final { scan-assembler-times "vrlb" 4 { target { le } } } } */ +/* { dg-final { scan-assembler-times "vspltisb" 4 { target { le } } } } */ + +/* Final uncompress instructions. */ + +/* { dg-final { scan-assembler-times {vucmpr[lh][nb]} 4 } } */ + diff --git a/gcc/testsuite/gcc.target/powerpc/future-vucmpr-vsx.c b/gcc/testsuite/gcc.target/powerpc/future-vucmpr-vsx.c new file mode 100644 index 00000000000..b8887f2a5e6 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/future-vucmpr-vsx.c @@ -0,0 +1,61 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mdejagnu-cpu=future -mvsx" } */ +/* { dg-require-effective-target powerpc_future_compile_ok } */ + +#include <altivec.h> + +vector unsigned short test_uncompresshn(vector unsigned char a, + vector unsigned int b) +{ + return vec_uncompresshn(a, b); +} + +vector unsigned int test_uncompresshb(vector unsigned short a, + vector unsigned short b) +{ + return vec_uncompresshb(a, b); +} + +vector unsigned long long test_uncompresshh(vector unsigned int a, + vector unsigned char b) +{ + return vec_uncompresshh(a, b); +} + +vector unsigned short test_uncompressln(vector unsigned char a, + vector unsigned int b) +{ + return vec_uncompressln(a, b); +} + +vector unsigned int test_uncompresslb(vector unsigned short a, + vector unsigned short b) +{ + return vec_uncompresslb(a, b); +} + +vector unsigned long long test_uncompresslh(vector unsigned int a, + vector unsigned char b) +{ + return vec_uncompresslh(a, b); +} + +/* BE: direct instructions, no splats or reverse. */ + +/* { dg-final { scan-assembler-not {vsplt[whb]} { target { be } } } } */ +/* { dg-final { scan-assembler-not {xxspltib} { target { be } } } } */ +/* { dg-final { scan-assembler-not {xxbr[wh]\M} { target { be } } } } */ +/* { dg-final { scan-assembler-not {vrlb} { target { be } } } } */ + +/* LE: splats and reverse-byte + rotate must appear. */ + +/* { dg-final { scan-assembler-times {vsplt[whb]} 6 { target { le } } } } */ + +/* { dg-final { scan-assembler-times "xxspltib" 6 { target { le } } } } */ + +/* { dg-final { scan-assembler-times {xxbr[wh]} 4 { target { le } } } } */ + +/* { dg-final { scan-assembler-times "vrlb" 6 { target { le } } } } */ + +/* { dg-final { scan-assembler-times {vucmpr[lh][nbh]} 6 } } */ + diff --git a/gcc/testsuite/gcc.target/powerpc/future-vupk.c b/gcc/testsuite/gcc.target/powerpc/future-vupk.c new file mode 100644 index 00000000000..7c642ed5c12 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/future-vupk.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mdejagnu-cpu=future" } */ +/* { dg-require-effective-target powerpc_future_compile_ok } */ + +#include <altivec.h> + +vector signed char +test_unpack_hsn_to_byte(vector unsigned long long a) +{ + return vec_unpack_hsn_to_byte(a); +} + +vector signed char +test_unpack_lsn_to_byte(vector unsigned long long a) +{ + return vec_unpack_lsn_to_byte(a); +} + +vector unsigned char +test_unpack_int4_to_bf16(vector unsigned short a) +{ + return vec_unpack_int4_to_bf16(a, 0); +} + +vector unsigned char +test_unpack_int8_to_bf16(vector unsigned short a) +{ + return vec_unpack_int8_to_bf16(a, 0); +} + +vector float +test_unpack_int4_to_fp32(vector unsigned int a) +{ + return vec_unpack_int4_to_fp32(a, 0); +} + +vector float +test_unpack_int8_to_fp32(vector unsigned int a) +{ + return vec_unpack_int8_to_fp32(a, 0); +} + + +/* { dg-final { scan-assembler-times "xxbrq" 2 { target { vsx_hw && le } } } } */ + +/* { dg-final { scan-assembler-times "vupkhsntob" 1 } } */ +/* { dg-final { scan-assembler-times "vupklsntob" 1 } } */ +/* { dg-final { scan-assembler-times "vupkint4tobf16" 1 } } */ +/* { dg-final { scan-assembler-times "vupkint8tobf16" 1 } } */ +/* { dg-final { scan-assembler-times "vupkint4tofp32" 1 } } */ +/* { dg-final { scan-assembler-times "vupkint8tofp32" 1 } } */ -- 2.52.0
