public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Bill Schmidt <wschmidt@linux.ibm.com>
To: gcc-patches@gcc.gnu.org
Cc: segher@kernel.crashing.org
Subject: [PATCH 08/14] Add support for parsing rs6000-bif.def.
Date: Tue, 04 Feb 2020 02:27:00 -0000	[thread overview]
Message-ID: <9310267079479df612a24ddded34b35f3b575024.1580782131.git.wschmidt@linux.ibm.com> (raw)
In-Reply-To: <cover.1580782131.git.wschmidt@linux.ibm.com>
In-Reply-To: <cover.1580782131.git.wschmidt@linux.ibm.com>

2020-02-03  Bill Schmidt  <wschmidt@linux.ibm.com>

        * config/rs6000/rs6000-genbif.c (MAXBIFSTANZAS): New defined
	constant.
        (bif_stanzas): New filescope variable.
        (curr_bif_stanza): Likewise.
        (fnkinds): New enum.
        (typelist): New	struct.
        (attrinfo): New	struct.
        (prototype): New struct.
	(MAXBIFS): New defined constant.
        (bifdata): New struct.
        (bifs):	New filescope variable.
        (curr_bif): Likewise.
        (parse_bif_args): New function.
        (parse_bif_attrs): New function.
        (parse_prototype): New function.
        (parse_bif_entry): New function.
        (parse_bif_stanza): New	function.
        (parse_bif): Implement.
---
 gcc/config/rs6000/rs6000-genbif.c | 473 +++++++++++++++++++++++++++++-
 1 file changed, 472 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-genbif.c b/gcc/config/rs6000/rs6000-genbif.c
index 38401224dce..e7ce777afbb 100644
--- a/gcc/config/rs6000/rs6000-genbif.c
+++ b/gcc/config/rs6000/rs6000-genbif.c
@@ -156,7 +156,23 @@ enum void_status {
   VOID_OK
 };
 
+/* Stanzas are groupings of built-in functions and overloads by some
+   common feature/attribute.  These definitions are for built-in function
+   stanzas.  */
+#define MAXBIFSTANZAS 256
+static char *bif_stanzas[MAXBIFSTANZAS];
 static int num_bif_stanzas;
+static int curr_bif_stanza;
+
+/* Function modifiers provide special handling for const, pure, and math
+   functions.  These are mutually exclusive, and therefore kept separate
+   from other bif attributes.  */
+enum fnkinds {
+  FNK_NONE,
+  FNK_CONST,
+  FNK_PURE,
+  FNK_MATH
+};
 
 /* Legal base types for an argument or return type.  */
 enum basetype {
@@ -199,7 +215,54 @@ struct typeinfo {
   int val2;
 };
 
+/* A list of argument types.  */
+struct typelist {
+  typeinfo info;
+  typelist *next;
+};
+
+/* Attributes of a builtin function.  */
+struct attrinfo {
+  char isinit;
+  char isset;
+  char isext;
+  char isnosoft;
+  char isldv;
+  char isstv;
+  char isreve;
+  char isabs;
+  char ispred;
+  char ishtm;
+};
+
+/* Fields associated with a function prototype (bif or overload).  */
+struct prototype {
+  typeinfo rettype;
+  char *bifname;
+  int nargs;
+  typelist *args;
+  int restr_opnd;
+  restriction restr;
+  int restr_val1;
+  int restr_val2;
+};
+
+/* Data associated with a builtin function, and a table of such data.  */
+#define MAXBIFS 16384
+struct bifdata {
+  int stanza;
+  fnkinds kind;
+  prototype proto;
+  char *idname;
+  char *patname;
+  attrinfo attrs;
+  char *fndecl;
+};
+
+static bifdata bifs[MAXBIFS];
 static int num_bifs;
+static int curr_bif;
+
 static int num_ovld_stanzas;
 static int num_ovlds;
 
@@ -747,11 +810,419 @@ match_type (typeinfo *typedata, int voidok)
   return match_basetype (typedata);
 }
 
+/* Parse the argument list, returning 1 if success or 0 if any
+   malformation is found.  */
+static int
+parse_bif_args (prototype *protoptr)
+{
+  typelist **argptr = &protoptr->args;
+  int *nargs = &protoptr->nargs;
+  int *restr_opnd = &protoptr->restr_opnd;
+  restriction *restr = &protoptr->restr;
+  int *val1 = &protoptr->restr_val1;
+  int *val2 = &protoptr->restr_val2;
+
+  int success;
+  *nargs = 0;
+
+  /* Start the argument list.  */
+  consume_whitespace ();
+  if (linebuf[pos] != '(')
+    {
+      (*diag) ("missing '(' at column %d.\n", pos + 1);
+      return 0;
+    }
+  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_opnd)
+	      {
+		(*diag) ("More than one restricted operand\n");
+		return 0;
+	      }
+	    *restr_opnd = *nargs;
+	    *restr = argtype->restr;
+	    *val1 = argtype->val1;
+	    *val2 = 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 0;
+	  }
+
+#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 = %d, val2 = %d, 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 0;
+	  }
+	safe_inc_pos ();
+      }
+  } while (success);
+
+  return 1;
+}
+
+/* Parse the attribute list, returning 1 if success or 0 if any
+   malformation is found.  */
+static int
+parse_bif_attrs (attrinfo *attrptr)
+{
+  consume_whitespace ();
+  if (linebuf[pos] != '{')
+    {
+      (*diag) ("missing attribute set at column %d.\n", pos + 1);
+      return 0;
+    }
+  safe_inc_pos ();
+
+  memset (attrptr, 0, sizeof (*attrptr));
+  char *attrname = NULL;
+
+  do {
+    consume_whitespace ();
+    int oldpos = pos;
+    attrname = match_identifier ();
+    if (attrname)
+      {
+	if (!strcmp (attrname, "init"))
+	  attrptr->isinit = 1;
+	else if (!strcmp (attrname, "set"))
+	  attrptr->isset = 1;
+	else if (!strcmp (attrname, "ext"))
+	  attrptr->isext = 1;
+	else if (!strcmp (attrname, "nosoft"))
+	  attrptr->isnosoft = 1;
+	else if (!strcmp (attrname, "ldv"))
+	  attrptr->isldv = 1;
+	else if (!strcmp (attrname, "stv"))
+	  attrptr->isstv = 1;
+	else if (!strcmp (attrname, "reve"))
+	  attrptr->isreve = 1;
+	else if (!strcmp (attrname, "abs"))
+	  attrptr->isabs = 1;
+	else if (!strcmp (attrname, "pred"))
+	  attrptr->ispred = 1;
+	else if (!strcmp (attrname, "htm"))
+	  attrptr->ishtm = 1;
+	else
+	  {
+	    (*diag) ("unknown attribute at column %d.\n", oldpos + 1);
+	    return 0;
+	  }
+
+	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 0;
+	  }
+      }
+    else
+      {
+	pos = oldpos;
+	if (linebuf[pos] != '}')
+	  {
+	    (*diag) ("badly terminated attr set at column %d.\n", pos + 1);
+	    return 0;
+	  }
+	safe_inc_pos ();
+      }
+  } while (attrname);
+
+#ifdef DEBUG
+  (*diag) ("attribute set: init = %d, set = %d, ext = %d, \
+nosoft = %d, ldv = %d, stv = %d, reve = %d, abs = %d, pred = %d, \
+htm = %d.\n",
+	   attrptr->isinit, attrptr->isset, attrptr->isext, attrptr->isnosoft,
+	   attrptr->isldv, attrptr->isstv, attrptr->isreve, attrptr->isabs,
+	   attrptr->ispred, attrptr->ishtm);
+#endif
+
+  return 1;
+}
+
+/* Parse a function prototype.  This code is shared by the bif and overload
+   file processing.  Return 1 for success, 0 for failure.  */
+static int
+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 0;
+    }
+
+#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 = %d, val2 = %d, 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 0;
+    }
+
+#ifdef DEBUG
+  (*diag) ("function name is '%s'.\n", *bifname);
+#endif
+
+  /* Process arguments.  */
+  if (!parse_bif_args (protoptr))
+    return 0;
+
+  /* Process terminating semicolon.  */
+  consume_whitespace ();
+  if (linebuf[pos] != ';')
+    {
+      (*diag) ("missing semicolon at column %d.\n", pos + 1);
+      return 0;
+    }
+  safe_inc_pos ();
+  consume_whitespace ();
+  if (linebuf[pos] != '\n')
+    {
+      (*diag) ("garbage at end of line at column %d.\n", pos + 1);
+      return 0;
+    }
+
+  return 1;
+}
+
+/* Parse a two-line entry for a built-in function.  Return 1 for
+   success, 2 for end-of-stanza, and 5 for a parsing error.  */
+static int
+parse_bif_entry ()
+{
+  /* Check for end of stanza.  */
+  pos = 0;
+  consume_whitespace ();
+  if (linebuf[pos] == '[')
+    return 2;
+
+  /* Allocate an entry in the bif table.  */
+  if (num_bifs >= MAXBIFS - 1)
+    {
+      (*diag) ("too many built-in functions.\n");
+      return 5;
+    }
+
+  curr_bif = num_bifs++;
+  bifs[curr_bif].stanza = curr_bif_stanza;
+
+  /* Read the first token and see if it is a function modifier.  */
+  consume_whitespace ();
+  int oldpos = pos;
+  char *token = match_identifier ();
+  if (!token)
+    {
+      (*diag) ("malformed entry at column %d\n", pos + 1);
+      return 5;
+    }
+
+  if (!strcmp (token, "const"))
+    bifs[curr_bif].kind = FNK_CONST;
+  else if (!strcmp (token, "pure"))
+    bifs[curr_bif].kind = FNK_PURE;
+  else if (!strcmp (token, "math"))
+    bifs[curr_bif].kind = FNK_MATH;
+  else
+    {
+      /* No function modifier, so push the token back.  */
+      pos = oldpos;
+      bifs[curr_bif].kind = FNK_NONE;
+    }
+
+  if (!parse_prototype (&bifs[curr_bif].proto))
+    return 5;
+
+  /* Now process line 2.  First up is the builtin id.  */
+  if (!advance_line (bif_file))
+    {
+      (*diag) ("unexpected EOF.\n");
+      return 5;
+    }
+
+  pos = 0;
+  consume_whitespace ();
+  oldpos = pos;
+  bifs[curr_bif].idname = match_identifier ();
+  if (!bifs[curr_bif].idname)
+    {
+      (*diag) ("missing builtin id at column %d.\n", pos + 1);
+      return 5;
+    }
+
+#ifdef DEBUG
+  (*diag) ("ID name is '%s'.\n", bifs[curr_bif].idname);
+#endif
+
+  /* Save the ID in a lookup structure.  */
+  if (!rbt_insert (&bif_rbt, bifs[curr_bif].idname))
+    {
+      (*diag) ("duplicate function ID '%s' at column %d.\n",
+	       bifs[curr_bif].idname, oldpos + 1);
+      return 5;
+    }
+
+  /* Now the pattern name.  */
+  consume_whitespace ();
+  bifs[curr_bif].patname = match_identifier ();
+  if (!bifs[curr_bif].patname)
+    {
+      (*diag) ("missing pattern name at column %d.\n", pos + 1);
+      return 5;
+    }
+
+#ifdef DEBUG
+  (*diag) ("pattern name is '%s'.\n", bifs[curr_bif].patname);
+#endif
+
+  /* Process attributes.  */
+  if (!parse_bif_attrs (&bifs[curr_bif].attrs))
+    return 5;
+
+  return 1;
+}
+
+/* Parse one stanza of the input BIF file.  linebuf already contains the
+   first line to parse.  Return 1 for success, 0 for EOF, 5 for failure.  */
+static int
+parse_bif_stanza ()
+{
+  /* Parse the stanza header.  */
+  pos = 0;
+  consume_whitespace ();
+
+  if (linebuf[pos] != '[')
+    {
+      (*diag) ("ill-formed stanza header at column %d.\n", pos + 1);
+      return 5;
+    }
+  safe_inc_pos ();
+
+  char *stanza_name = match_identifier ();
+  if (!stanza_name)
+    {
+      (*diag) ("no identifier found in stanza header.\n");
+      return 5;
+    }
+
+  /* Add the identifier to a table and set the number to be recorded
+     with subsequent bif entries.  */
+  if (num_bif_stanzas >= MAXBIFSTANZAS)
+    {
+      (*diag) ("too many stanza headers.\n");
+      return 5;
+    }
+
+  curr_bif_stanza = num_bif_stanzas;
+  bif_stanzas[num_bif_stanzas++] = stanza_name;
+
+  if (linebuf[pos] != ']')
+    {
+      (*diag) ("ill-formed stanza header at column %d.\n", pos + 1);
+      return 5;
+    }
+  safe_inc_pos ();
+
+  consume_whitespace ();
+  if (linebuf[pos] != '\n' && pos != LINELEN - 1)
+    {
+      (*diag) ("garbage after stanza header.\n");
+      return 5;
+    }
+
+  int result = 1;
+
+  while (result != 2) /* end of stanza  */
+    {
+      int result;
+      if (!advance_line (bif_file))
+	return 0;
+
+      result = parse_bif_entry();
+      if (!result) /* EOF */
+	return 0;
+      else if (result > 2)
+	return 5;
+    }
+
+  return 1;
+}
+
 /* Parse the built-in file.  Return 1 for success, 5 for a parsing failure.  */
 static int
 parse_bif ()
 {
-  return 1;
+  int result;
+  diag = &bif_diag;
+  while (1)
+    {
+      if (!advance_line (bif_file))
+	return 1;
+
+      /* Parse a stanza beginning at this line.  */
+      result = parse_bif_stanza ();
+      if (result != 1)
+	break;
+    }
+  if (result == 0)
+    return 1;
+  return result;
 }
 
 /* Parse the overload file.  Return 1 for success, 6 for a parsing error.  */
-- 
2.17.1

  parent reply	other threads:[~2020-02-04  2:27 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-04  2:26 [PATCH 00/14] rs6000: Begin replacing built-in support Bill Schmidt
2020-02-04  2:26 ` [PATCH 02/14] Add stubs for input files. These will grow much larger Bill Schmidt
2020-02-04  2:26 ` [PATCH 01/14] Initial create of rs6000-genbif.c Bill Schmidt
2020-02-04 18:27   ` Segher Boessenkool
2020-02-04 21:10     ` Bill Schmidt
2020-02-04 22:36       ` Segher Boessenkool
2020-02-04 22:44         ` Bill Schmidt
2020-02-04 23:48           ` Segher Boessenkool
2020-02-04  2:27 ` [PATCH 06/14] Red-black tree implementation for balanced tree search Bill Schmidt
2020-02-04  2:27 ` [PATCH 13/14] Write code to rs6000-bif.c Bill Schmidt
2020-02-04  2:27 ` [PATCH 09/14] Add parsing support for rs6000-overload.def Bill Schmidt
2020-02-04  2:27 ` [PATCH 12/14] Write code to rs6000-bif.h Bill Schmidt
2020-02-04  2:27 ` [PATCH 11/14] Write #defines to rs6000-vecdefines.h Bill Schmidt
2020-02-04  2:27 ` Bill Schmidt [this message]
2020-02-04  2:27 ` [PATCH 10/14] Build function type identifiers and store them Bill Schmidt
2020-02-04  2:27 ` [PATCH 05/14] Add support functions for matching types Bill Schmidt
2020-02-04  2:27 ` [PATCH 07/14] Add main function with stub functions for parsing and output Bill Schmidt
2020-02-04  2:27 ` [PATCH 04/14] Support functions to parse whitespace, lines, identifiers, integers Bill Schmidt
2020-02-04  2:27 ` [PATCH 14/14] Incorporate new code into the build machinery Bill Schmidt
2020-02-04  2:27 ` [PATCH 03/14] Add file support and functions for diagnostic support Bill Schmidt
2020-02-04 17:40 ` [PATCH 00/14] rs6000: Begin replacing built-in support Segher Boessenkool
2020-02-05  7:57   ` Richard Biener
2020-02-05 12:30     ` Segher Boessenkool
2020-02-05 13:01       ` Bill Schmidt
2020-02-14 18:34   ` Mike Stump
2020-02-14 21:27     ` Segher Boessenkool
2020-02-15  0:14       ` Mike Stump

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9310267079479df612a24ddded34b35f3b575024.1580782131.git.wschmidt@linux.ibm.com \
    --to=wschmidt@linux.ibm.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=segher@kernel.crashing.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).