2021-06-07  Bill Schmidt  <wschm...@linux.ibm.com>

gcc/
        * config/rs6000/rs6000-gen-builtins.c (parse_args): New function.
        (parse_prototype): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 142 ++++++++++++++++++++++++
 1 file changed, 142 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index ca103d0fdaa..15c0c5a6634 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1059,6 +1059,91 @@ match_type (typeinfo *typedata, int voidok)
   return 1;
 }
 
+/* Parse the argument list.  */
+static parse_codes
+parse_args (prototype *protoptr)
+{
+  typelist **argptr = &protoptr->args;
+  int *nargs = &protoptr->nargs;
+  int *restr_opnd = protoptr->restr_opnd;
+  restriction *restr = protoptr->restr;
+  char **val1 = protoptr->restr_val1;
+  char **val2 = protoptr->restr_val2;
+  int restr_cnt = 0;
+
+  int success;
+  *nargs = 0;
+
+  /* Start the argument list.  */
+  consume_whitespace ();
+  if (linebuf[pos] != '(')
+    {
+      (*diag) ("missing '(' at column %d.\n", pos + 1);
+      return PC_PARSEFAIL;
+    }
+  safe_inc_pos ();
+
+  do {
+    consume_whitespace ();
+    int oldpos = pos;
+    typelist *argentry = (typelist *) malloc (sizeof (typelist));
+    memset (argentry, 0, sizeof *argentry);
+    typeinfo *argtype = &argentry->info;
+    success = match_type (argtype, VOID_NOTOK);
+    if (success)
+      {
+       if (argtype->restr)
+         {
+           if (restr_cnt >= MAXRESTROPNDS)
+             {
+               (*diag) ("More than two %d operands\n", MAXRESTROPNDS);
+               return PC_PARSEFAIL;
+             }
+           restr_opnd[restr_cnt] = *nargs + 1;
+           restr[restr_cnt] = argtype->restr;
+           val1[restr_cnt] = argtype->val1;
+           val2[restr_cnt++] = argtype->val2;
+         }
+       (*nargs)++;
+       *argptr = argentry;
+       argptr = &argentry->next;
+       consume_whitespace ();
+       if (linebuf[pos] == ',')
+         safe_inc_pos ();
+       else if (linebuf[pos] != ')')
+         {
+           (*diag) ("arg not followed by ',' or ')' at column %d.\n",
+                    pos + 1);
+           return PC_PARSEFAIL;
+         }
+
+#ifdef DEBUG
+       (*diag) ("argument type: isvoid = %d, isconst = %d, isvector = %d, \
+issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, ispointer = %d, \
+base = %d, restr = %d, val1 = \"%s\", val2 = \"%s\", pos = %d.\n",
+                argtype->isvoid, argtype->isconst, argtype->isvector,
+                argtype->issigned, argtype->isunsigned, argtype->isbool,
+                argtype->ispixel, argtype->ispointer, argtype->base,
+                argtype->restr, argtype->val1, argtype->val2, pos + 1);
+#endif
+      }
+    else
+      {
+       free (argentry);
+       *argptr = NULL;
+       pos = oldpos;
+       if (linebuf[pos] != ')')
+         {
+           (*diag) ("badly terminated arg list at column %d.\n", pos + 1);
+           return PC_PARSEFAIL;
+         }
+       safe_inc_pos ();
+      }
+  } while (success);
+
+  return PC_OK;
+}
+
 /* Parse the attribute list.  */
 static parse_codes
 parse_bif_attrs (attrinfo *attrptr)
@@ -1071,6 +1156,63 @@ parse_bif_attrs (attrinfo *attrptr)
 static parse_codes
 parse_prototype (prototype *protoptr)
 {
+  typeinfo *ret_type = &protoptr->rettype;
+  char **bifname = &protoptr->bifname;
+
+  /* Get the return type.  */
+  consume_whitespace ();
+  int oldpos = pos;
+  int success = match_type (ret_type, VOID_OK);
+  if (!success)
+    {
+      (*diag) ("missing or badly formed return type at column %d.\n",
+              oldpos + 1);
+      return PC_PARSEFAIL;
+    }
+
+#ifdef DEBUG
+  (*diag) ("return type: isvoid = %d, isconst = %d, isvector = %d, \
+issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, ispointer = %d, \
+base = %d, restr = %d, val1 = \"%s\", val2 = \"%s\", pos = %d.\n",
+          ret_type->isvoid, ret_type->isconst, ret_type->isvector,
+          ret_type->issigned, ret_type->isunsigned, ret_type->isbool,
+          ret_type->ispixel, ret_type->ispointer, ret_type->base,
+          ret_type->restr, ret_type->val1, ret_type->val2, pos + 1);
+#endif
+
+  /* Get the bif name.  */
+  consume_whitespace ();
+  oldpos = pos;
+  *bifname = match_identifier ();
+  if (!*bifname)
+    {
+      (*diag) ("missing function name at column %d.\n", oldpos + 1);
+      return PC_PARSEFAIL;
+    }
+
+#ifdef DEBUG
+  (*diag) ("function name is '%s'.\n", *bifname);
+#endif
+
+  /* Process arguments.  */
+  if (parse_args (protoptr) == PC_PARSEFAIL)
+    return PC_PARSEFAIL;
+
+  /* Process terminating semicolon.  */
+  consume_whitespace ();
+  if (linebuf[pos] != ';')
+    {
+      (*diag) ("missing semicolon at column %d.\n", pos + 1);
+      return PC_PARSEFAIL;
+    }
+  safe_inc_pos ();
+  consume_whitespace ();
+  if (linebuf[pos] != '\n')
+    {
+      (*diag) ("garbage at end of line at column %d.\n", pos + 1);
+      return PC_PARSEFAIL;
+    }
+
   return PC_OK;
 }
 
-- 
2.27.0

Reply via email to