https://gcc.gnu.org/g:0982dc7bf700e201c5ccea28d109c7ee0a39edf0
commit 0982dc7bf700e201c5ccea28d109c7ee0a39edf0 Author: Michael Meissner <[email protected]> Date: Sat Jul 18 02:51:38 2026 -0400 DMF patch 10 Add support for the DMF (Dense Math Facility) and MMA+ (Matrix-Multiply Assist Plus) builtins and instructions which may be available on a future Power processor. This patch extends the existing MMA infrastructure to support Dense Math Registers (DMRs). Key changes: 1. Extended MMA operand support from 7 to 9 operands (MAX_MMA_OPERANDS) 2. Added new DMF-specific unspecs: * UNSPEC_DMF_DMXOR for DMR XOR operations * UNSPEC_DMF_DMXVI8GERX4* for DMR GER (outer product) operations * UNSPEC_DMF_PMDMXVI8GERX4* for prefixed DMR GER operations * UNSPEC_DMF_DMSETDMRZ for zeroing a DMR register 3. Implemented new instruction patterns in mma.md: * dmf_build_dmr: Build a DMR from eight vector operands * dmf_dmsetdmrz: Zero a DMR register * dmf_dmxor: XOR operation on DMR registers * dmf_dmxvi8gerx4/dmxvi8gerx4pp: DMR outer product operations * dmf_pmdmxvi8gerx4/pmdmxvi8gerx4pp: Prefixed DMR outer product operations 4. Added new DMF builtins and updated GIMPLE folding: * Added DMF and MMA+ builtins * Updated GIMPLE folding to handle DMR pass-by-reference semantics * Extended builtin expansion to support up to 9 operand instructions 5. Added documentation for the new DMF and MMA+ builtins. The implementation follows the existing MMA pattern where user-facing builtins use pass-by-reference for DMR arguments, while internal builtins use pass-by-value for optimization. 2026-07-15 Peter Bergner <[email protected]> Surya Kumari Jangala <[email protected]> Kishan Parmar <[email protected]> gcc/ * config/rs6000/mma.md (MAX_MMA_OPERANDS): Increase from 7 to 9. (UNSPEC_DMF_DMXOR): New unspec. (UNSPEC_DMF_DMXVI8GERX4): Likewise. (UNSPEC_DMF_DMXVI8GERX4PP): Likewise. (UNSPEC_DMF_PMDMXVI8GERX4): Likewise. (UNSPEC_DMF_PMDMXVI8GERX4PP): Likewise. (UNSPEC_DMF_DMSETDMRZ): Likewise. (DMF_PV): New iterator. (DMF_DPV): Likewise. (DMF_PVI8I4I4): Likewise. (DMF_DPVI8I4I4): Likewise. (pv): Add DMF mappings. (apv): Likewise. (pvi8i4i4): New attribute. (dpvi8i4i4): Likewise. (dmf_build_dmr): New define_expand. (dmf_dmsetdmrz): New insn. (dmf_dmxor): Likewise. (dmf_<pv>): New insn pattern. (dmf_<apv>): Likewise. (dmf_<pvi8i4i4>): Likewise. (dmf_<dpvi8i4i4>): Likewise. * config/rs6000/rs6000-builtin.cc (rs6000_gimple_fold_mma_builtin): Add DMF builtin support. Handle DMR pass-by-reference semantics. Support up to nine builtin operands. (mma_expand_builtin): Likewise. (rs6000_expand_builtin): Handle DMF builtins. * config/rs6000/rs6000-builtins.def: Add DMF and MMA+ builtin definitions. * doc/extend.texi (PowerPC Matrix-Multiply Assist Built-in Functions): Document MMA+ builtins. (PowerPC Dense Math Facility Built-in Functions): Document DMF builtins. gcc/testsuite/ * gcc.target/powerpc/dmf-build-dmr.c: New test. * gcc.target/powerpc/dmf-builtin.c: New test. Diff: --- gcc/config/rs6000/mma.md | 126 ++++++++++++++++++++++- gcc/config/rs6000/rs6000-builtin.cc | 84 ++++++++++----- gcc/config/rs6000/rs6000-builtins.def | 55 ++++++++++ gcc/doc/extend.texi | 38 +++++++ gcc/testsuite/gcc.target/powerpc/dmf-build-dmr.c | 15 +++ gcc/testsuite/gcc.target/powerpc/dmf-builtin.c | 81 +++++++++++++++ 6 files changed, 372 insertions(+), 27 deletions(-) diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index 85caa19ee10b..8d4a65a48b16 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -24,7 +24,7 @@ ;; __vector_pair types that the MMA built-in functions reference. We ;; use OPAQUE_MODE to prevent anything from trying to open them up. -(define_constants [(MAX_MMA_OPERANDS 7)]) +(define_constants [(MAX_MMA_OPERANDS 9)]) ;; Constants for creating unspecs @@ -96,6 +96,12 @@ UNSPEC_DMF_INSERT1024 UNSPEC_DMF_RELOAD_FROM_MEMORY UNSPEC_DMF_RELOAD_TO_MEMORY + UNSPEC_DMF_DMXOR + UNSPEC_DMF_DMXVI8GERX4 + UNSPEC_DMF_DMXVI8GERX4PP + UNSPEC_DMF_PMDMXVI8GERX4 + UNSPEC_DMF_PMDMXVI8GERX4PP + UNSPEC_DMF_DMSETDMRZ ]) (define_c_enum "unspecv" @@ -138,12 +144,18 @@ ;; MMA instructions with 1 vector pair and 1 vector arguments (define_int_iterator MMA_PV [UNSPEC_MMA_XVF64GER]) +; DMF instructions with 1 vector pair and 1 vector arguments +(define_int_iterator DMF_PV [UNSPEC_DMF_DMXVI8GERX4]) + ;; MMA instructions with 1 accumulator, 1 vector pair and 1 vector arguments (define_int_iterator MMA_APV [UNSPEC_MMA_XVF64GERPP UNSPEC_MMA_XVF64GERPN UNSPEC_MMA_XVF64GERNP UNSPEC_MMA_XVF64GERNN]) +;; DMF instructions with 1 dmr, 1 vector pair and 1 vector arguments +(define_int_iterator DMF_DPV [UNSPEC_DMF_DMXVI8GERX4PP]) + ;; MMA instructions with 2 vector, 2 4-bit and 1 8-bit arguments (define_int_iterator MMA_VVI4I4I8 [UNSPEC_MMA_PMXVI4GER8]) @@ -193,6 +205,14 @@ (define_int_iterator MMA_AVVI4I4I4 [UNSPEC_MMA_PMXVI8GER4PP UNSPEC_MMA_PMXVI8GER4SPP]) +; DMF instructions with 1 vector pair, 1 vector and 1 8-bit and 2 4-bit +;; arguments +(define_int_iterator DMF_PVI8I4I4 [UNSPEC_DMF_PMDMXVI8GERX4]) + +;; DMF instructions with 1 dmr, 1 vector pair, 1 vector and 1 8-bit and +;; 2 4-bit arguments +(define_int_iterator DMF_DPVI8I4I4 [UNSPEC_DMF_PMDMXVI8GERX4PP]) + (define_int_attr acc [(UNSPEC_MMA_XXMFACC "xxmfacc") (UNSPEC_MMA_XXMTACC "xxmtacc")]) @@ -222,12 +242,14 @@ (UNSPEC_MMA_XVF32GERNP "xvf32gernp") (UNSPEC_MMA_XVF32GERNN "xvf32gernn")]) -(define_int_attr pv [(UNSPEC_MMA_XVF64GER "xvf64ger")]) +(define_int_attr pv [(UNSPEC_MMA_XVF64GER "xvf64ger") + (UNSPEC_DMF_DMXVI8GERX4 "dmxvi8gerx4")]) (define_int_attr apv [(UNSPEC_MMA_XVF64GERPP "xvf64gerpp") (UNSPEC_MMA_XVF64GERPN "xvf64gerpn") (UNSPEC_MMA_XVF64GERNP "xvf64gernp") - (UNSPEC_MMA_XVF64GERNN "xvf64gernn")]) + (UNSPEC_MMA_XVF64GERNN "xvf64gernn") + (UNSPEC_DMF_DMXVI8GERX4PP "dmxvi8gerx4pp")]) (define_int_attr vvi4i4i8 [(UNSPEC_MMA_PMXVI4GER8 "pmxvi4ger8")]) @@ -268,6 +290,9 @@ (define_int_attr avvi4i4i4 [(UNSPEC_MMA_PMXVI8GER4PP "pmxvi8ger4pp") (UNSPEC_MMA_PMXVI8GER4SPP "pmxvi8ger4spp")]) +(define_int_attr pvi8i4i4 [(UNSPEC_DMF_PMDMXVI8GERX4 "pmdmxvi8gerx4")]) + +(define_int_attr dpvi8i4i4 [(UNSPEC_DMF_PMDMXVI8GERX4PP "pmdmxvi8gerx4pp")]) ;; Vector pair support. OOmode can only live in VSRs. (define_expand "movoo" @@ -682,6 +707,30 @@ DONE; }) +(define_expand "dmf_build_dmr" + [(match_operand:TDO 0 "dmr_register_operand") + (match_operand:V16QI 1 "mma_assemble_input_operand") + (match_operand:V16QI 2 "mma_assemble_input_operand") + (match_operand:V16QI 3 "mma_assemble_input_operand") + (match_operand:V16QI 4 "mma_assemble_input_operand") + (match_operand:V16QI 5 "mma_assemble_input_operand") + (match_operand:V16QI 6 "mma_assemble_input_operand") + (match_operand:V16QI 7 "mma_assemble_input_operand") + (match_operand:V16QI 8 "mma_assemble_input_operand")] + "TARGET_DMF" +{ + rtx vp0 = gen_reg_rtx (OOmode); + rtx vp1 = gen_reg_rtx (OOmode); + rtx vp2 = gen_reg_rtx (OOmode); + rtx vp3 = gen_reg_rtx (OOmode); + emit_insn (gen_vsx_assemble_pair (vp0, operands[2], operands[1])); + emit_insn (gen_vsx_assemble_pair (vp1, operands[4], operands[3])); + emit_insn (gen_vsx_assemble_pair (vp2, operands[6], operands[5])); + emit_insn (gen_vsx_assemble_pair (vp3, operands[8], operands[7])); + emit_insn (gen_dm_insert1024 (operands[0], vp0, vp1, vp2, vp3)); + DONE; +}) + (define_expand "mma_disassemble_acc" [(match_operand:V16QI 0 "mma_disassemble_output_operand") (match_operand:XO 1 "accumulator_operand") @@ -759,6 +808,13 @@ "xxsetaccz %A0" [(set_attr "type" "mma")]) +(define_insn "dmf_dmsetdmrz" + [(set (match_operand:TDO 0 "dmr_register_operand" "=wD") + (unspec:TDO [(const_int 0)] UNSPEC_DMF_DMSETDMRZ))] + "TARGET_DMF" + "dmsetdmrz %0" + [(set_attr "type" "dmf")]) + (define_insn "mma_<vv>" [(set (match_operand:XO 0 "fpr_reg_operand" "=&d,&d") (unspec:XO [(match_operand:V16QI 1 "vsx_register_operand" "v,?wa") @@ -927,3 +983,67 @@ "<avvi4i4i4> %A0,%x2,%x3,%4,%5,%6" [(set_attr "type" "mma") (set_attr "prefixed" "yes")]) + +(define_insn "dmf_dmxor" + [(set (match_operand:TDO 0 "dmr_register_operand" "=wD") + (unspec:TDO [(match_operand:TDO 1 "dmr_register_operand" "0") + (match_operand:TDO 2 "dmr_register_operand" "wD")] + UNSPEC_DMF_DMXOR))] + "TARGET_DMF" + "dmxor %0,%2" + [(set_attr "type" "dmf")]) + +(define_insn "dmf_<pv>" + [(set (match_operand:TDO 0 "accumulator_operand" "=wD") + (unspec:TDO [(match_operand:OO 1 "vsx_register_operand" "wa") + (match_operand:V16QI 2 "vsx_register_operand" "wa")] + DMF_PV))] + "TARGET_DMF" +{ + return "<pv> %0,%x1,%x2"; +} + [(set_attr "type" "dmf")]) + +(define_insn "dmf_<apv>" + [(set (match_operand:TDO 0 "accumulator_operand" "=wD") + (unspec:TDO [(match_operand:TDO 1 "accumulator_operand" "0") + (match_operand:OO 2 "vsx_register_operand" "wa") + (match_operand:V16QI 3 "vsx_register_operand" "wa")] + DMF_DPV))] + "TARGET_DMF" +{ + return "<apv> %0,%x2,%x3"; +} + [(set_attr "type" "dmf")]) + +(define_insn "dmf_<pvi8i4i4>" + [(set (match_operand:TDO 0 "dmr_register_operand" "=wD") + (unspec:TDO [(match_operand:OO 1 "vsx_register_operand" "wa") + (match_operand:V16QI 2 "vsx_register_operand" "wa") + (match_operand:SI 3 "u8bit_cint_operand" "n") + (match_operand:SI 4 "const_0_to_15_operand" "n") + (match_operand:SI 5 "const_0_to_15_operand" "n")] + DMF_PVI8I4I4))] + "TARGET_DMF" +{ + return "<pvi8i4i4> %0,%x1,%x2,%3,%4,%5"; +} + [(set_attr "type" "dmf") + (set_attr "prefixed" "yes")]) + +(define_insn "dmf_<dpvi8i4i4>" + [(set (match_operand:TDO 0 "dmr_register_operand" "=wD") + (unspec:TDO [(match_operand:TDO 1 "dmr_register_operand" "0") + (match_operand:OO 2 "vsx_register_operand" "wa") + (match_operand:V16QI 3 "vsx_register_operand" "wa") + (match_operand:SI 4 "u8bit_cint_operand" "n") + (match_operand:SI 5 "const_0_to_15_operand" "n") + (match_operand:SI 6 "const_0_to_15_operand" "n")] + DMF_DPVI8I4I4))] + "TARGET_DMF" +{ + return "<dpvi8i4i4> %0,%x2,%x3,%4,%5,%6"; +} + [(set_attr "type" "dmf") + (set_attr "prefixed" "yes")]) + diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc index 4ecbbe43ba00..0c6d961d7a7d 100644 --- a/gcc/config/rs6000/rs6000-builtin.cc +++ b/gcc/config/rs6000/rs6000-builtin.cc @@ -1121,7 +1121,8 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi, gimple *stmt = gsi_stmt (*gsi); size_t fncode = (size_t) fn_code; - if (!bif_is_mma (rs6000_builtin_info[fncode])) + if (!bif_is_mma (rs6000_builtin_info[fncode]) + && !bif_is_dm (rs6000_builtin_info[fncode])) return false; /* Each call that can be gimple-expanded has an associated built-in @@ -1129,11 +1130,11 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi, already expanded it! Exceptions: lxvp and stxvp. */ if (rs6000_builtin_info[fncode].assoc_bif == RS6000_BIF_NONE && fncode != RS6000_BIF_LXVP - && fncode != RS6000_BIF_STXVP) + && fncode != RS6000_BIF_STXVP + && fncode != RS6000_BIF_DMMR) return false; bifdata *bd = &rs6000_builtin_info[fncode]; - unsigned nopnds = bd->nargs; gimple_seq new_seq = NULL; gimple *new_call; tree new_decl; @@ -1249,27 +1250,49 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi, /* Convert this built-in into an internal version that uses pass-by-value arguments. The internal built-in is found in the assoc_bif field. */ - new_decl = rs6000_builtin_decls[rs6000_builtin_info[fncode].assoc_bif]; + size_t new_fncode = rs6000_builtin_info[fncode].assoc_bif; + new_decl = rs6000_builtin_decls[new_fncode]; tree lhs, op[MAX_MMA_OPERANDS]; + tree lhs_type = NULL_TREE; tree acc = gimple_call_arg (stmt, 0); push_gimplify_context (true); - if (bif_is_quad (*bd)) + switch (insn_data[rs6000_builtin_info[new_fncode].icode].operand[0].mode) { - /* This built-in has a pass-by-reference accumulator input, so load it - into a temporary accumulator for use as a pass-by-value input. */ - op[0] = make_ssa_name (vector_quad_type_node); - for (unsigned i = 1; i < nopnds; i++) - op[i] = gimple_call_arg (stmt, i); - gimplify_assign (op[0], build_simple_mem_ref (acc), &new_seq); + case TDOmode: + lhs_type = dmr1024_type_node; + break; + case XOmode: + lhs_type = vector_quad_type_node; + break; + case OOmode: + lhs_type = vector_pair_type_node; + break; + default: + gcc_unreachable (); } - else - { - /* This built-in does not use its pass-by-reference accumulator argument - as an input argument, so remove it from the input list. */ - nopnds--; - for (unsigned i = 0; i < nopnds; i++) - op[i] = gimple_call_arg (stmt, i + 1); + + unsigned nopnds = 0; + for (int i = 0; i < bd->nargs; i++) + { + tree arg = gimple_call_arg (stmt, i); + if (i == 0 && !bif_is_dmr (*bd) && !bif_is_quad (*bd)) + continue; + /* If this is another DMR operand, it is passed in by reference. + The internal built-ins use pass-by-value, so load this operand + into a variable and pass that in as our operand. */ + if (POINTER_TYPE_P (TREE_TYPE (arg)) + && types_compatible_p (TREE_TYPE (TREE_TYPE (arg)), lhs_type)) + { + tree op_mem = build_simple_mem_ref (build1 (NOP_EXPR, + TREE_TYPE (arg), + arg)); + op[nopnds] = make_ssa_name (lhs_type); + gimplify_assign (op[nopnds], op_mem, &new_seq); + } + else + op[nopnds] = arg; + nopnds++; } switch (nopnds) @@ -1301,14 +1324,19 @@ rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi, new_call = gimple_build_call (new_decl, 7, op[0], op[1], op[2], op[3], op[4], op[5], op[6]); break; + case 8: + new_call = gimple_build_call (new_decl, 8, op[0], op[1], op[2], op[3], + op[4], op[5], op[6], op[7]); + break; + case 9: + new_call = gimple_build_call (new_decl, 9, op[0], op[1], op[2], op[3], + op[4], op[5], op[6], op[7], op[8]); + break; default: gcc_unreachable (); } - if (fncode == RS6000_BIF_BUILD_PAIR || fncode == RS6000_BIF_ASSEMBLE_PAIR_V) - lhs = make_ssa_name (vector_pair_type_node); - else - lhs = make_ssa_name (vector_quad_type_node); + lhs = make_ssa_name (lhs_type); gimple_call_set_lhs (new_call, lhs); gimple_seq_add_stmt (&new_seq, new_call); gimplify_assign (build_simple_mem_ref (acc), lhs, &new_seq); @@ -3025,6 +3053,14 @@ mma_expand_builtin (tree exp, rtx target, insn_code icode, case 7: pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5], op[6]); break; + case 8: + pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5], op[6], + op[7]); + break; + case 9: + pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5], op[6], + op[7], op[8]); + break; default: gcc_unreachable (); } @@ -3567,7 +3603,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */, /* Position of first argument (0 for void-returning functions, else 1). */ int k; /* Modes for the return value, if any, and arguments. */ - const int MAX_BUILTIN_ARGS = 6; + const int MAX_BUILTIN_ARGS = 8; machine_mode mode[MAX_BUILTIN_ARGS + 1]; if (void_func) @@ -3702,7 +3738,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */, if (bif_is_lxvrze (*bifaddr)) return lxvrze_expand_builtin (target, icode, op, mode[0], mode[1]); - if (bif_is_mma (*bifaddr)) + if (bif_is_mma (*bifaddr) || bif_is_dm (*bifaddr)) return mma_expand_builtin (exp, target, icode, fcode); if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node) diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def index 85486c70f0d7..2c0bc1d0119b 100644 --- a/gcc/config/rs6000/rs6000-builtins.def +++ b/gcc/config/rs6000/rs6000-builtins.def @@ -4095,3 +4095,58 @@ const vf __builtin_altivec_unpack_int8_to_fp32 (vui, const int<2>); VUPKINT8TOFP32 altivec_vupkint8tofp32 {} + +[dm] + void __builtin_dmsetdmrz (dmr1024 *); + DMSETDMRZ nothing {dm,dmint} + + dmr1024 __builtin_dmsetdmrz_internal (); + DMSETDMRZ_INTERNAL dmf_dmsetdmrz {dm} + + void __builtin_dmmr (dmr1024 *, dmr1024 *); + DMMR nothing {dm,dmint} + + dmr1024 __builtin_dmmr_internal (dmr1024); + DMMR_INTERNAL movtdo {dm} + + void __builtin_dmxor (dmr1024 *, dmr1024 *); + DMXOR nothing {dm,dmint,dmr} + + dmr1024 __builtin_dmxor_internal (dmr1024, dmr1024); + DMXOR_INTERNAL dmf_dmxor {dm} + + void __builtin_build_dmr (dmr1024 *, vuc, vuc, vuc, vuc, vuc, vuc, vuc, vuc); + BUILD_DMR nothing {dm,dmint} + + dmr1024 __builtin_build_dmr_internal (vuc, vuc, vuc, vuc, vuc, vuc, vuc, vuc); + BUILD_DMR_INTERNAL dmf_build_dmr {dm} + + void __builtin_mma_dmxvi8gerx4 (dmr1024 *, v256, vuc); + DMXVI8GERX4 nothing {dm,dmint} + + dmr1024 __builtin_mma_dmxvi8gerx4_internal (v256, vuc); + DMXVI8GERX4_INTERNAL dmf_dmxvi8gerx4 {dm} + + void __builtin_mma_dmxvi8gerx4pp (dmr1024 *, v256, vuc); + DMXVI8GERX4PP nothing {dm,dmint,dmr} + + dmr1024 __builtin_mma_dmxvi8gerx4pp_internal (dmr1024, v256, vuc); + DMXVI8GERX4PP_INTERNAL dmf_dmxvi8gerx4pp {dm} + + void __builtin_mma_pmdmxvi8gerx4 (dmr1024 *, v256, vuc, const int<8>, \ + const int<4>, const int<4>); + PMDMXVI8GERX4 nothing {dm,pair,dmint} + + dmr1024 __builtin_mma_pmdmxvi8gerx4_internal (v256, vuc, const int<8>, \ + const int<4>, const int<4>); + PMDMXVI8GERX4_INTERNAL dmf_pmdmxvi8gerx4 {dm,pair} + + void __builtin_mma_pmdmxvi8gerx4pp (dmr1024 *, v256, vuc, const int<8>, \ + const int<4>, const int<4>); + PMDMXVI8GERX4PP nothing {dm,pair,dmint,dmr} + + dmr1024 __builtin_mma_pmdmxvi8gerx4pp_internal (dmr1024, v256, vuc, \ + const int<8>, const int<4>, \ + const int<4>); + PMDMXVI8GERX4PP_INTERNAL dmf_pmdmxvi8gerx4pp {dm,pair} + diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 4761b07973a7..6bd1e8247add 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -18714,6 +18714,7 @@ instructions, but allow the compiler to schedule those calls. * PowerPC Hardware Transactional Memory Built-in Functions:: * PowerPC Atomic Memory Operation Functions:: * PowerPC Matrix-Multiply Assist Built-in Functions:: +* PowerPC Dense Math Facility Built-in Functions:: * PRU Built-in Functions:: * RISC-V Built-in Functions:: * RISC-V Vector Intrinsics:: @@ -27468,6 +27469,43 @@ __vector_pair __builtin_vsx_lxvp (size_t, __vector_pair *); void __builtin_vsx_stxvp (__vector_pair, size_t, __vector_pair *); @end smallexample +Future ISA of PowerPC may add new Matrix-Multiply Assist Plus (MMA+) +instructions. GCC provides support for these instructions through the +following built-in functions which are enabled with the @code{-mmma} option. +The vec_t type below is defined to be a normal vector unsigned char type. +The uint2, uint4 and uint8 parameters are 2-bit, 4-bit and 8-bit unsigned +integer constants respectively. The compiler will verify that they are +constants and that their values are within range. The __dmr1024 type is a +1024-bit integer type. + +The built-in functions supported are: + +@smallexample +void __builtin_mma_dmxvi8gerx4 (__dmr1024 *, __vector_pair, vec_t); +void __builtin_mma_dmxvi8gerx4pp (__dmr1024 *, __vector_pair, vec_t); + +void __builtin_mma_pmdmxvi8gerx4 (__dmr1024 *, __vector_pair, vec_t, uint8, uint4, uint4); +void __builtin_mma_pmdmxvi8gerx4pp (__dmr1024 *, __vector_pair, vec_t, uint8, uint4, uint4); +@end smallexample + +@node PowerPC Dense Math Facility Built-in Functions +@subsection PowerPC Dense Math Facility Built-in Functions + +A future PowerPC processor may provide Dense Math Facility (DMF) +instructions. GCC provides support for these instructions through the +following built-in functions which are enabled with the @code{-mdense-math} +option. The vec_t type below is defined to be a normal vector unsigned char +type. The __dmr1024 type is a 1024 bit integer type. + +The built-in functions supported are: + +@smallexample +void __builtin_dmsetdmrz (__dmr1024 *); +void __builtin_dmmr (__dmr1024 *, __dmr1024 *); +void __builtin_dmxor (__dmr1024 *, __dmr1024 *); +void __builtin_build_dmr (__dmr1024 *, vec_t, vec_t, vec_t, vec_t, vec_t, vec_t, vec_t, vec_t); +@end smallexample + @node PRU Built-in Functions @subsection PRU Built-in Functions diff --git a/gcc/testsuite/gcc.target/powerpc/dmf-build-dmr.c b/gcc/testsuite/gcc.target/powerpc/dmf-build-dmr.c new file mode 100644 index 000000000000..d5e85e64e27e --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/dmf-build-dmr.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_future_compile_ok } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-mdejagnu-cpu=future -O2" } */ + +typedef unsigned char vec_t __attribute__((vector_size(16))); + +void +foo2 (__dmr1024 *dst, vec_t *src) +{ + __builtin_build_dmr (dst, src[0], src[1], src[2], src[3], src[4], src[5], src[6], src[7]); +} + +/* { dg-final { scan-assembler-times {\mdmxxinstdmr512\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mlxv\M} 8 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/dmf-builtin.c b/gcc/testsuite/gcc.target/powerpc/dmf-builtin.c new file mode 100644 index 000000000000..02bbebf69f82 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/dmf-builtin.c @@ -0,0 +1,81 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target powerpc_future_compile_ok } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-mdejagnu-cpu=future -O2" } */ + +typedef unsigned char vec_t __attribute__((vector_size(16))); + +void +foo (__dmr1024 *dst, __vector_pair *vpp, vec_t *src) +{ + __dmr1024 dmr; + __vector_pair vp = *vpp; + vec_t vec = *src; + __builtin_dmsetdmrz (&dmr); + __builtin_mma_dmxvi8gerx4 (&dmr, vp, vec); + *dst = dmr; +} + +void +bar (__dmr1024 *dst, __vector_pair *vpp, vec_t *src) +{ + __dmr1024 dmr = dst[0]; + __vector_pair vp = *vpp; + vec_t vec = *src; + __builtin_mma_dmxvi8gerx4 (&dmr, vp, vec); + dst[1] = dmr; +} + +/* { dg-final { scan-assembler-times {\mdmxvi8gerx4\M} 2 } } */ + +void +foo_1 (__dmr1024 *dst, __vector_pair *vpp, vec_t *src) +{ + __dmr1024 dmr; + __vector_pair vp = *vpp; + vec_t vec = *src; + __builtin_dmsetdmrz (&dmr); + __builtin_mma_dmxvi8gerx4pp (&dmr, vp, vec); + *dst = dmr; +} + +void +bar_1 (__dmr1024 *dst, __vector_pair *vpp, vec_t *src) +{ + __dmr1024 dmr = dst[0];; + __vector_pair vp = *vpp; + vec_t vec = *src; + __builtin_mma_dmxvi8gerx4pp (&dmr, vp, vec); + dst[1] = dmr; +} + +/* { dg-final { scan-assembler-times {\mdmxvi8gerx4pp\M} 2 } } */ + +void +foo_2 (__dmr1024 *dst, __vector_pair *vpp, vec_t *src) +{ + __vector_pair vp = *vpp; + vec_t vec = *src; + __builtin_mma_pmdmxvi8gerx4 (dst, vp, vec, 255, 15, 2); +} + +/* { dg-final { scan-assembler-times {\mpmdmxvi8gerx4\M} 1 } } */ + +void +foo_3 (__dmr1024 *dst, __vector_pair *vpp, vec_t *src) +{ + __vector_pair vp = *vpp; + vec_t vec = *src; + __builtin_mma_pmdmxvi8gerx4pp (dst, vp, vec, 255, 15, 2); +} + +/* { dg-final { scan-assembler-times {\mpmdmxvi8gerx4pp\M} 1 } } */ + + +void +foo_5 (__dmr1024 *dst, __dmr1024 *src) +{ + __builtin_dmxor (dst, src); +} + +/* { dg-final { scan-assembler-times {\mdmxor\M} 1 } } */
