Hello,

Below patch is bootstrapped and regtested on Power64le-linux-gnu.

Thank You,
Kishan

Add the initial infrastructure required to support Dense Math Facility
(DMF) builtins.

Extend the builtin generator with a new "dm" stanza, ENB_DM enable flag,
DMR base type, and DM-specific builtin attributes used for Dense Math
builtins.  Also add TARGET_DMF builtin enablement checks.

These changes provide the foundation for subsequent Dense Math builtin
support for a future Power ISA that may or may not be implemented in
future Power processor and the builtin interfaces may change
accordingly.

2026-07-13  Kishan Parmar  <[email protected]>

gcc/ChangeLog
        * config/rs6000/rs6000-builtin.cc (rs6000_invalid_builtin): Add
        ENB_DM diagnostic.
        (rs6000_builtin_is_supported): Handle ENB_DM.
        * config/rs6000/rs6000-gen-builtins.cc: Update comments for new
        Dense Math builtin attributes.
        (bif_stanza): Add BSTZ_DM.
        (stanza_map): Add "dm" stanza.
        (enable_string): Add ENB_DM.
        (basetype): Add BT_DMR.
        (attrinfo): Add isdm, isdmint and isdmr fields.
        (type_map): Add dmr1024 and ptr_dmr1024 type mappings.
        (match_type): Recognize dmr1024 type.
        (parse_bif_attrs): Parse dm, dmint and dmr attributes.
        (complete_vector_type): Handle BT_DMR.
        (write_decls): Emit ENB_DM and Dense Math builtin attribute bits
        and predicates.
        (write_bif_static_init): Initialize Dense Math builtin attributes
        and associate dmint builtins with their internal variants.
---
 gcc/config/rs6000/rs6000-builtin.cc      |  5 ++
 gcc/config/rs6000/rs6000-gen-builtins.cc | 63 +++++++++++++++++++++---
 2 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-builtin.cc 
b/gcc/config/rs6000/rs6000-builtin.cc
index e3aab2b6ef1..2d35d586124 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -150,6 +150,9 @@ rs6000_invalid_builtin (enum rs6000_gen_builtins fncode)
       error ("%qs requires the %qs and %qs options", name, "-mcpu=future",
             "-mvsx");
       break;
+    case ENB_DM:
+      error ("%qs requires the %qs option", name, "-mdense-math");
+      break;
     default:
     case ENB_ALWAYS:
       gcc_unreachable ();
@@ -211,6 +214,8 @@ rs6000_builtin_is_supported (enum rs6000_gen_builtins 
fncode)
       return TARGET_FUTURE && TARGET_ALTIVEC;
     case ENB_FUTURE_VSX:
       return TARGET_FUTURE && TARGET_VSX;
+    case ENB_DM:
+      return TARGET_DMF;
     default:
       gcc_unreachable ();
     }
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.cc 
b/gcc/config/rs6000/rs6000-gen-builtins.cc
index 28ba90cea0f..08068ba78fd 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.cc
+++ b/gcc/config/rs6000/rs6000-gen-builtins.cc
@@ -94,6 +94,9 @@ along with GCC; see the file COPYING3.  If not see
      ibmld    Restrict usage to the case when TFmode is IBM-128
      ibm128   Restrict usage to the case where __ibm128 is supported or
               if ibmld
+     dm       Needs special handling for DMF/MMA+ instructions
+     dmint    DMF/MMA+ instruction expanding to internal call at GIMPLE time
+     dmr      MMA+ instruction using a dmr register as an input operand
 
    An example stanza might look like this:
 
@@ -235,6 +238,7 @@ enum bif_stanza
  BSTZ_FUTURE,
  BSTZ_FUTURE_ALTIVEC,
  BSTZ_FUTURE_VSX,
+ BSTZ_DM,
  NUMBIFSTANZAS
 };
 
@@ -271,7 +275,8 @@ static stanza_entry stanza_map[NUMBIFSTANZAS] =
     { "mma",           BSTZ_MMA        },
     { "future",        BSTZ_FUTURE     },
     { "future-altivec", BSTZ_FUTURE_ALTIVEC },
-    { "future-vsx",    BSTZ_FUTURE_VSX }
+    { "future-vsx",    BSTZ_FUTURE_VSX },
+    { "dm",            BSTZ_DM         }
   };
 
 static const char *enable_string[NUMBIFSTANZAS] =
@@ -299,7 +304,8 @@ static const char *enable_string[NUMBIFSTANZAS] =
     "ENB_MMA",
     "ENB_FUTURE",
     "ENB_FUTURE_ALTIVEC",
-    "ENB_FUTURE_VSX"
+    "ENB_FUTURE_VSX",
+    "ENB_DM"
   };
 
 /* Function modifiers provide special handling for const, pure, and fpmath
@@ -333,7 +339,8 @@ enum basetype
   BT_DECIMAL128,
   BT_IBM128,
   BT_VPAIR,
-  BT_VQUAD
+  BT_VQUAD,
+  BT_DMR
 };
 
 /* Ways in which a const int value can be restricted.  RES_BITS indicates
@@ -401,6 +408,9 @@ struct attrinfo
   bool isendian;
   bool isibmld;
   bool isibm128;
+  bool isdm;
+  bool isdmint;
+  bool isdmr;
 };
 
 /* Fields associated with a function prototype (bif or overload).  */
@@ -552,6 +562,7 @@ static typemap type_map[] =
     { "pv16qi",                "ptr_V16QI" },
     { "pv1poi",                "ptr_vector_pair" },
     { "pv1pxi",                "ptr_vector_quad" },
+    { "pv1tdoi",       "ptr_dmr1024" },
     { "pv1ti",         "ptr_V1TI" },
     { "pv2df",         "ptr_V2DF" },
     { "pv2di",         "ptr_V2DI" },
@@ -582,6 +593,7 @@ static typemap type_map[] =
     { "v16qi",         "V16QI" },
     { "v1poi",         "vector_pair" },
     { "v1pxi",         "vector_quad" },
+    { "v1tdoi",        "dmr1024" },
     { "v1ti",          "V1TI" },
     { "v2df",          "V2DF" },
     { "v2di",          "V2DI" },
@@ -1067,6 +1079,7 @@ match_type (typeinfo *typedata, int voidok)
        vd      vector double
        v256    __vector_pair
        v512    __vector_quad
+       dmr1024 __dmr1024
 
      For simplicity, We don't support "short int" and "long long int".
      We don't currently support a <basetype> of "_Float16".  "signed"
@@ -1248,6 +1261,13 @@ match_type (typeinfo *typedata, int voidok)
       handle_pointer (typedata);
       return 1;
     }
+  else if (!strcmp (token, "dmr1024"))
+    {
+      typedata->isvector = 1;
+      typedata->base = BT_DMR;
+      handle_pointer (typedata);
+      return 1;
+    }
   else if (!strcmp (token, "signed"))
     typedata->issigned = 1;
   else if (!strcmp (token, "unsigned"))
@@ -1446,6 +1466,12 @@ parse_bif_attrs (attrinfo *attrptr)
          attrptr->isibmld = 1;
        else if (!strcmp (attrname, "ibm128"))
          attrptr->isibm128 = 1;
+       else if (!strcmp (attrname, "dm"))
+         attrptr->isdm = 1;
+       else if (!strcmp (attrname, "dmint"))
+         attrptr->isdmint = 1;
+       else if (!strcmp (attrname, "dmr"))
+         attrptr->isdmr = 1;
        else
          {
            diag (oldpos, "unknown attribute.\n");
@@ -1479,14 +1505,15 @@ parse_bif_attrs (attrinfo *attrptr)
        "pred = %d, htm = %d, htmspr = %d, htmcr = %d, mma = %d, "
        "quad = %d, pair = %d, mmaint = %d, no32bit = %d, 32bit = %d, "
        "cpu = %d, ldstmask = %d, lxvrse = %d, lxvrze = %d, endian = %d, "
-       "ibmdld = %d, ibm128 = %d.\n",
+       "ibmdld = %d, ibm128 = %d, dm = %d, dmint = %d, dmr = %d.\n",
        attrptr->isextract, attrptr->isnosoft,attrptr->isldvec,
        attrptr->isstvec, attrptr->isreve, attrptr->ispred, attrptr->ishtm,
        attrptr->ishtmspr, attrptr->ishtmcr, attrptr->ismma,
        attrptr->isquad, attrptr->ispair, attrptr->ismmaint,
        attrptr->isno32bit, attrptr->is32bit, attrptr->iscpu,
        attrptr->isldstmask, attrptr->islxvrse, attrptr->islxvrze,
-       attrptr->isendian, attrptr->isibmld, attrptr->isibm128);
+       attrptr->isendian, attrptr->isibmld, attrptr->isibm128,
+       attrptr->isdm, attrptr->isdmint, attrptr->isdmr);
 #endif
 
   return PC_OK;
@@ -1547,6 +1574,10 @@ complete_vector_type (typeinfo *typeptr, char *buf, int 
*bufi)
       memcpy (&buf[*bufi], "1pxi", 4);
       *bufi += 4;
       break;
+    case BT_DMR:
+      memcpy (&buf[*bufi], "1tdoi", 5);
+      *bufi += 5;
+      break;
     default:
       diag (pos, "unhandled basetype %d.\n", typeptr->base);
       exit (1);
@@ -2261,7 +2292,8 @@ write_decls (void)
   fprintf (header_file, "  ENB_MMA,\n");
   fprintf (header_file, "  ENB_FUTURE,\n");
   fprintf (header_file, "  ENB_FUTURE_ALTIVEC,\n");
-  fprintf (header_file, "  ENB_FUTURE_VSX\n");
+  fprintf (header_file, "  ENB_FUTURE_VSX,\n");
+  fprintf (header_file, "  ENB_DM\n");
   fprintf (header_file, "};\n\n");
 
   fprintf (header_file, "#define PPC_MAXRESTROPNDS 3\n");
@@ -2303,6 +2335,9 @@ write_decls (void)
   fprintf (header_file, "#define bif_endian_bit\t\t(0x00200000)\n");
   fprintf (header_file, "#define bif_ibmld_bit\t\t(0x00400000)\n");
   fprintf (header_file, "#define bif_ibm128_bit\t\t(0x00800000)\n");
+  fprintf (header_file, "#define bif_dm_bit\t\t(0x02000000)\n");
+  fprintf (header_file, "#define bif_dmint_bit\t\t(0x04000000)\n");
+  fprintf (header_file, "#define bif_dmr_bit\t\t(0x08000000)\n");
   fprintf (header_file, "\n");
   fprintf (header_file,
           "#define bif_is_extract(x)\t((x).bifattrs & bif_extract_bit)\n");
@@ -2348,6 +2383,12 @@ write_decls (void)
           "#define bif_is_ibmld(x)\t((x).bifattrs & bif_ibmld_bit)\n");
   fprintf (header_file,
           "#define bif_is_ibm128(x)\t((x).bifattrs & bif_ibm128_bit)\n");
+  fprintf (header_file,
+          "#define bif_is_dm(x)\t((x).bifattrs & bif_dm_bit)\n");
+  fprintf (header_file,
+          "#define bif_is_dmint(x)\t((x).bifattrs & bif_dmint_bit)\n");
+  fprintf (header_file,
+          "#define bif_is_dmr(x)\t((x).bifattrs & bif_dmr_bit)\n");
   fprintf (header_file, "\n");
 
   fprintf (header_file,
@@ -2547,6 +2588,12 @@ write_bif_static_init (void)
        fprintf (init_file, " | bif_ibmld_bit");
       if (bifp->attrs.isibm128)
        fprintf (init_file, " | bif_ibm128_bit");
+      if (bifp->attrs.isdm)
+       fprintf (init_file, " | bif_dm_bit");
+      if (bifp->attrs.isdmint)
+       fprintf (init_file, " | bif_dmint_bit");
+      if (bifp->attrs.isdmr)
+       fprintf (init_file, " | bif_dmr_bit");
       fprintf (init_file, ",\n");
       fprintf (init_file, "      /* restr_opnd */\t{%d, %d, %d},\n",
               bifp->proto.restr_opnd[0], bifp->proto.restr_opnd[1],
@@ -2580,8 +2627,8 @@ write_bif_static_init (void)
                   : (bifp->kind == FNK_FPMATH ? "= fp, const"
                      : ""))));
       fprintf (init_file, "      /* assoc_bif */\tRS6000_BIF_%s%s\n",
-              bifp->attrs.ismmaint ? bifp->idname : "NONE",
-              bifp->attrs.ismmaint ? "_INTERNAL" : "");
+              (bifp->attrs.ismmaint || bifp->attrs.isdmint) ? bifp->idname : 
"NONE",
+              (bifp->attrs.ismmaint || bifp->attrs.isdmint) ? "_INTERNAL" : 
"");
       fprintf (init_file, "    },\n");
     }
   fprintf (init_file, "  };\n\n");
-- 
2.52.0

Reply via email to