This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

HANDLE_PRAGMA overhaul


This patch replaces HANDLE_PRAGMA by a new mechanism that works with
the integrated preprocessor.  Most of it is modifications to
machine-specific code for machines I do not have.  I have built
cross-compilers from i386-linux to each affected target to verify that
the code all compiles, but I cannot test the changes properly.  I've
also run a complete bootstrap with a native i386-linux compiler, but
that target does not use this mechanism.

Affected targets are: arm c4x h8300 i370 i960 sh v850.

In some cases I had to make unrelated modifications to get the cross
compiler to build.

zw

	* c-pragma.h: Define HANDLE_GENERIC_PRAGMAS if
	REGISTER_TARGET_PRAGMAS is defined.  Duplicate some
	definitions from cpplib.h.
	* cpplib.h: Don't typedef struct cpp_reader if c-pragma.h has
	already done it.
	* tm.texi: Document HANDLE_PRAGMA as no longer supported.  Add
	documentation for REGISTER_TARGET_PRAGMAS.

	* c-lex.c: Include cpplib.h before c-pragma.h.  Define a
	default-pragma callback to implement -Wunknown-pragmas if
	USE_CPPLIB.
	* c-parse.in: Move all includes to top of file.
	* c-pragma.c: Include cpplib.h before c-pragma.h.  Include
	tm_p.h.
	(dispatch_pragma): Put the namespace in the -Wunknown-pragmas
	warning.
	(init_pragma): If REGISTER_TARGET_PRAGMAS is defined, call it.

	* arm.h, arm-protos.h, arm.c,
	  c4x.h, c4x-protos.h, c4x.c,
	  h8300.h, h8300-protos.h, h8300.c,
	  i370.h, i370-protos.h, i370.c,
	  i960.h, i960-protos.h, i960.c,
	  sh.h, sh-protos.h, sh.c, 
	  v850.h, v850-protos.h, v850.c: Convert HANDLE_PRAGMA-based
	pragmata scheme to use REGISTER_TARGET_PRAGMAS instead.

	* d30v.h: Don't mention HANDLE_PRAGMA in comment.  Add
	multiple include guard.
	* i370.md (untyped_call): Use GEN_CALL.
	(umodsi3): Remove unused variable.
	* sh/elf.h: Don't undef HANDLE_SYSV_PRAGMA.
	* v850.c (output_move_single, output_move_double): Constify
	return value.
	(print_operand): Constify a char *.
	* v850.h (struct small_memory_info): Constify name member.

===================================================================
Index: c-lex.c
--- c-lex.c	2000/09/07 00:37:08	1.97
+++ c-lex.c	2000/09/07 17:00:23
@@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA.  */
 #include "c-tree.h"
 #include "flags.h"
 #include "timevar.h"
+#include "cpplib.h"
 #include "c-pragma.h"
 #include "toplev.h"
 #include "intl.h"
@@ -52,8 +53,6 @@ Boston, MA 02111-1307, USA.  */
 #define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ((ENV_VALUE) = getenv (ENV_NAME))
 #endif
 
-#include "cpplib.h"
-
 #if USE_CPPLIB
 extern cpp_reader  parse_in;
 #else
@@ -162,6 +161,7 @@ static void cb_ident		PARAMS ((cpp_reade
 static void cb_enter_file	PARAMS ((cpp_reader *));
 static void cb_leave_file	PARAMS ((cpp_reader *));
 static void cb_rename_file	PARAMS ((cpp_reader *));
+static void cb_def_pragma	PARAMS ((cpp_reader *));
 #endif
 
 
@@ -210,6 +210,7 @@ init_c_lex (filename)
   parse_in.cb.enter_file = cb_enter_file;
   parse_in.cb.leave_file = cb_leave_file;
   parse_in.cb.rename_file = cb_rename_file;
+  parse_in.cb.def_pragma = cb_def_pragma;
 
   /* Make sure parse_in.digraphs matches flag_digraphs.  */
   CPP_OPTION (&parse_in, digraphs) = flag_digraphs;
@@ -776,6 +777,27 @@ cb_rename_file (pfile)
   update_header_times (ip->nominal_fname);
   /* Hook for C++.  */
   extract_interface_info ();
+}
+
+static void
+cb_def_pragma (pfile)
+     cpp_reader *pfile;
+{
+  /* Issue a warning message if we have been asked to do so.  Ignore
+     unknown pragmas in system headers unless an explicit
+     -Wunknown-pragmas has been given. */
+  if (warn_unknown_pragmas > in_system_header)
+    {
+      const unsigned char *space, *name;
+      const cpp_token *t = pfile->first_directive_token + 2;
+
+      space = t[0].val.node->name;
+      name  = t[1].type == CPP_NAME ? t[1].val.node->name : 0;
+      if (name)
+	warning ("ignoring #pragma %s %s", space, name);
+      else
+	warning ("ignoring #pragma %s", space);
+    }
 }
 #endif /* USE_CPPLIB */
 
===================================================================
Index: c-parse.in
--- c-parse.in	2000/09/07 00:37:09	1.54
+++ c-parse.in	2000/09/07 17:00:24
@@ -41,6 +41,9 @@ end ifc
 #include <setjmp.h>
 #include "tree.h"
 #include "input.h"
+#include "cpplib.h"
+#include "intl.h"
+#include "timevar.h"
 #include "c-lex.h"
 #include "c-tree.h"
 #include "c-pragma.h"
@@ -2797,9 +2800,6 @@ end ifobjc
 
 /* yylex() is a thin wrapper around c_lex(), all it does is translate
    cpplib.h's token codes into yacc's token codes.  */
-#include "cpplib.h"
-#include "intl.h"
-#include "timevar.h"
 
 static enum cpp_ttype last_token;
 #if USE_CPPLIB
===================================================================
Index: c-pragma.c
--- c-pragma.c	2000/09/07 00:37:09	1.34
+++ c-pragma.c	2000/09/07 17:00:24
@@ -24,12 +24,13 @@ Boston, MA 02111-1307, USA.  */
 #include "tree.h"
 #include "function.h"
 #include "defaults.h"
+#include "cpplib.h"
 #include "c-pragma.h"
 #include "flags.h"
 #include "toplev.h"
 #include "ggc.h"
 #include "c-lex.h"
-#include "cpplib.h"
+#include "tm_p.h"
 
 #ifdef HANDLE_GENERIC_PRAGMAS
 
@@ -383,7 +384,7 @@ dispatch_pragma ()
   enum cpp_ttype t;
   tree x;
   const struct pragma_entry *p;
-  const char *name;
+  const char *name, *space = 0;
   size_t len;
 
   p = pragmas;
@@ -407,6 +408,7 @@ dispatch_pragma ()
 	{
 	  if (p->isnspace)
 	    {
+	      space = p->name;
 	      p = p->u.space;
 	      goto new_space;
 	    }
@@ -420,10 +422,15 @@ dispatch_pragma ()
     }
 
   /* Issue a warning message if we have been asked to do so.  Ignore
-     unknown pragmas in system header file unless an explcit
+     unknown pragmas in system headers unless an explicit
      -Wunknown-pragmas has been given. */
   if (warn_unknown_pragmas > in_system_header)
-    warning ("ignoring pragma %s", name);
+    {
+      if (space)
+	warning ("ignoring #pragma %s %s", space, name);
+      else
+	warning ("ignoring #pragma %s", name);
+    }
 }
 
 #endif
@@ -442,6 +449,10 @@ init_pragma ()
 #endif
 #ifdef HANDLE_PRAGMA_WEAK
   cpp_register_pragma (pfile, 0, "weak", handle_pragma_weak);
+#endif
+
+#ifdef REGISTER_TARGET_PRAGMAS
+  REGISTER_TARGET_PRAGMAS (pfile);
 #endif
 
 #ifdef HANDLE_PRAGMA_PACK_PUSH_POP
===================================================================
Index: c-pragma.h
--- c-pragma.h	2000/09/07 00:37:09	1.15
+++ c-pragma.h	2000/09/07 17:00:24
@@ -62,7 +62,8 @@ extern int add_weak PARAMS ((const char 
    parsing is to be done.  The code in GCC's generic C source files
    will only look for the definition of this constant.  They will
    ignore definitions of HANDLE_PRAGMA_PACK and so on.  */
-#if defined HANDLE_PRAGMA_PACK || defined HANDLE_PRAGMA_WEAK
+#if defined HANDLE_PRAGMA_PACK || defined HANDLE_PRAGMA_WEAK \
+    || defined REGISTER_TARGET_PRAGMAS
 #define HANDLE_GENERIC_PRAGMAS
 #endif
 
@@ -75,6 +76,17 @@ extern void dispatch_pragma PARAMS ((voi
 
 #else
 # define init_pragma()
+#endif
+
+/* Duplicate prototypes for the register_pragma stuff and the typedef for
+   cpp_reader, to avoid dragging cpplib.h in almost everywhere... */
+#ifndef __GCC_CPPLIB__
+typedef struct cpp_reader cpp_reader;
+
+extern void cpp_register_pragma PARAMS ((cpp_reader *,
+					 const char *, const char *,
+					 void (*) PARAMS ((cpp_reader *))));
+extern void cpp_register_pragma_space PARAMS ((cpp_reader *, const char *));
 #endif
 
 #endif /* _C_PRAGMA_H */
===================================================================
Index: cpplib.h
--- cpplib.h	2000/08/17 17:52:48	1.118
+++ cpplib.h	2000/09/07 17:00:24
@@ -28,7 +28,10 @@ Foundation, 59 Temple Place - Suite 330,
 extern "C" {
 #endif
 
+/* For complex reasons, cpp_reader is also typedefed in c-pragma.h.  */
+#ifndef _C_PRAGMA_H
 typedef struct cpp_reader cpp_reader;
+#endif
 typedef struct cpp_buffer cpp_buffer;
 typedef struct cpp_options cpp_options;
 typedef struct cpp_printer cpp_printer;
===================================================================
Index: tm.texi
--- tm.texi	2000/08/29 00:44:21	1.143
+++ tm.texi	2000/09/07 17:00:27
@@ -7774,33 +7774,62 @@ C++, which is to pretend that the file's
 @samp{extern "C" @{@dots{}@}}.
 
 @findex HANDLE_PRAGMA
+@item HANDLE_PRAGMA (@var{getc}, @var{ungetc}, @var{name})
+This macro is no longer supported.  You must use
+@code{REGISTER_TARGET_PRAGMAS} instead.
+
+@findex REGISTER_TARGET_PRAGMAS
 @findex #pragma
 @findex pragma
-@item HANDLE_PRAGMA (@var{getc}, @var{ungetc}, @var{name})
-Define this macro if you want to implement any pragmas.  If defined, it
-is a C expression whose value is 1 if the pragma was handled by the
-macro, zero otherwise.  The argument @var{getc} is a function of type
-@samp{int (*)(void)} which will return the next character in the input
-stream, or EOF if no characters are left.  The argument @var{ungetc} is
-a function of type @samp{void (*)(int)} which will push a character back
-into the input stream.  The argument @var{name} is the word following
-#pragma in the input stream.  The input stream pointer will be pointing
-just beyond the end of this word.  The input stream should be left
-undistrubed if the expression returns zero, otherwise it should be
-pointing at the next character after the end of the pragma.  Any
-characters remaining on the line will be ignored.
-
-It is generally a bad idea to implement new uses of @code{#pragma}.  The
-only reason to define this macro is for compatibility with other
-compilers that do support @code{#pragma} for the sake of any user
-programs which already use it.
+@item REGISTER_TARGET_PRAGMAS (@var{pfile})
+Define this macro if you want to implement any target-specific pragmas.
+If defined, it is a C expression which makes a series of calls to the
+@code{cpp_register_pragma} and/or @code{cpp_register_pragma_space}
+functions.  The @var{pfile} argument is the first argument to supply to
+these functions.  The macro may also do setup required for the pragmas.
 
+The primary reason to define this macro is to provide compatibility with
+other compilers for the same target.  In general, we discourage
+definition of target-specific pragmas for GCC.
+
 If the pragma can be implemented by atttributes then the macro
 @samp{INSERT_ATTRIBUTES} might be a useful one to define as well.
+
+Preprocessor macros that appear on pragma lines are not expanded.  All
+@samp{#pragma} directives that do not match any registered pragma are
+silently ignored, unless the user specifies @samp{-Wunknown-pragmas}.
+
+@deftypefun void cpp_register_pragma (cpp_reader *@var{pfile}, const char *@var{space}, const char *@var{name}, void (*@var{callback}) (cpp_reader *))
+
+Each call to @code{cpp_register_pragma} establishes one pragma.  The
+@var{callback} routine will be called when the preprocessor encounters a
+pragma of the form
+
+@smallexample
+#pragma [@var{space}] @var{name} @dots{}
+@end smallexample
+
+@var{space} must have been the subject of a previous call to
+@code{cpp_register_pragma_space}, or else be a null pointer.  The
+callback routine receives @var{pfile} as its first argument, but must
+not use it for anything (this may change in the future).  It may read
+any text after the @var{name} by making calls to @code{c_lex}.  Text
+which is not read by the callback will be silently ignored.
+
+Note that both @var{space} and @var{name} are case sensitive.
+
+For an example use of this routine, see @file{c4x.h} and the callback
+routines defined in @file{c4x.c}.
+@end deftypefun
+
+@deftypefun void cpp_register_pragma_space (cpp_reader *@var{pfile}, const char *@var{space})
+This routine establishes a namespace for pragmas, which will be
+registered by subsequent calls to @code{cpp_register_pragma}.  For
+example, pragmas defined by the C standard are in the @samp{STDC}
+namespace, and pragmas specific to GCC are in the @samp{GCC} namespace.
 
-Note: older versions of this macro only had two arguments: @var{stream}
-and @var{token}.  The macro was changed in order to allow it to work
-when gcc is built both with and without a cpp library.
+For an example use of this routine in a target header, see @file{v850.h}.
+@end deftypefun
 
 @findex HANDLE_SYSV_PRAGMA
 @findex #pragma
===================================================================
Index: config/arm/arm-protos.h
--- config/arm/arm-protos.h	2000/08/15 13:32:11	1.12
+++ config/arm/arm-protos.h	2000/09/07 17:00:27
@@ -20,11 +20,12 @@ along with GNU CC; see the file COPYING.
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#ifndef GCC_ARM_PROTOS_H
+#define GCC_ARM_PROTOS_H
+
 extern void   arm_override_options	PARAMS ((void));
 extern int    use_return_insn		PARAMS ((int));
 extern int    arm_regno_class 		PARAMS ((int));
-extern int    arm_process_pragma	PARAMS ((int (*)(void), void (*) (int),
-						char *));
 extern void   arm_finalize_pic		PARAMS ((void));
 extern int    arm_volatile_func		PARAMS ((void));
 extern const char * arm_output_epilogue	PARAMS ((int));
@@ -194,3 +195,11 @@ extern int  arm_dllimport_p 		PARAMS ((t
 extern void arm_mark_dllexport 		PARAMS ((tree));
 extern void arm_mark_dllimport 		PARAMS ((tree));
 #endif
+
+#ifdef _C_PRAGMA_H  /* included from code that cares about pragmas */
+extern void arm_pr_long_calls		PARAMS ((cpp_reader *));
+extern void arm_pr_no_long_calls	PARAMS ((cpp_reader *));
+extern void arm_pr_long_calls_off	PARAMS ((cpp_reader *));
+#endif
+
+#endif /* GCC_ARM_PROTOS_H */
===================================================================
Index: config/arm/arm.c
--- config/arm/arm.c	2000/09/03 17:49:32	1.105
+++ config/arm/arm.c	2000/09/07 17:00:29
@@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA.  */
 #include "system.h"
 #include "rtl.h"
 #include "tree.h"
-#include "tm_p.h"
+#include "tm.h"
 #include "regs.h"
 #include "hard-reg-set.h"
 #include "real.h"
@@ -42,6 +42,7 @@ Boston, MA 02111-1307, USA.  */
 #include "recog.h"
 #include "ggc.h"
 #include "except.h"
+#include "c-pragma.h"
 #include "tm_p.h"
 
 /* Forward definitions of types.  */
@@ -1613,27 +1614,27 @@ typedef enum
 
 static arm_pragma_enum arm_pragma_long_calls = OFF;
 
-/* Handle pragmas for compatibility with Intel's compilers.
-   FIXME: This is incomplete, since it does not handle all
-   the pragmas that the Intel compilers understand.  */
-int
-arm_process_pragma (p_getc, p_ungetc, pname)
-     int (*  p_getc)   PARAMS ((void)) ATTRIBUTE_UNUSED;
-     void (* p_ungetc) PARAMS ((int))  ATTRIBUTE_UNUSED;
-     char *  pname;
-{
-  /* Should be pragma 'far' or equivalent for callx/balx here.  */
-  if (strcmp (pname, "long_calls") == 0)
-    arm_pragma_long_calls = LONG;
-  else if (strcmp (pname, "no_long_calls") == 0)
-    arm_pragma_long_calls = SHORT;
-  else if (strcmp (pname, "long_calls_off") == 0)
-    arm_pragma_long_calls = OFF;
-  else
-    return 0;
-  
-  return 1;
+void
+arm_pr_long_calls (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  arm_pragma_long_calls = LONG;
 }
+
+void
+arm_pr_no_long_calls (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  arm_pragma_long_calls = SHORT;
+}
+
+void
+arm_pr_long_calls_off (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  arm_pragma_long_calls = OFF;
+}
+
 
 /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
    attribute for TYPE.  The attributes in ATTRIBUTES have previously been
===================================================================
Index: config/arm/arm.h
--- config/arm/arm.h	2000/08/25 16:58:34	1.82
+++ config/arm/arm.h	2000/09/07 17:00:29
@@ -2488,8 +2488,12 @@ extern int making_const_table;
   arm_set_default_type_attributes (TYPE)
 
 /* Handle pragmas for compatibility with Intel's compilers.  */
-#define HANDLE_PRAGMA(GET, UNGET, NAME) arm_process_pragma (GET, UNGET, NAME)
-
+#define REGISTER_TARGET_PRAGMAS(PFILE) do { \
+  cpp_register_pragma (PFILE, 0, "long_calls", arm_pr_long_calls); \
+  cpp_register_pragma (PFILE, 0, "no_long_calls", arm_pr_no_long_calls); \
+  cpp_register_pragma (PFILE, 0, "long_calls_off", arm_pr_long_calls_off); \
+} while (0)
+
 /* Condition code information. */
 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
    return the mode to be used for the comparison. 
===================================================================
Index: config/c4x/c4x-protos.h
--- config/c4x/c4x-protos.h	2000/07/30 09:12:46	1.8
+++ config/c4x/c4x-protos.h	2000/09/07 17:00:29
@@ -22,6 +22,9 @@
    the Free Software Foundation, 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#ifndef GCC_C4X_PROTOS_H
+#define GCC_C4X_PROTOS_H
+
 extern void c4x_override_options PARAMS ((void));
 
 extern void c4x_optimization_options PARAMS ((int, int));
@@ -290,3 +293,14 @@ extern enum machine_mode c4x_caller_save
 
 extern int c4x_rpts_cycles;	        /* Max cycles for RPTS.  */
 extern int c4x_cpu_version;		/* Cpu version C30/31/32/40/44.  */
+
+#ifdef _C_PRAGMA_H
+extern void c4x_pr_CODE_SECTION		PARAMS ((cpp_reader *));
+extern void c4x_pr_DATA_SECTION		PARAMS ((cpp_reader *));
+extern void c4x_pr_FUNC_IS_PURE		PARAMS ((cpp_reader *));
+extern void c4x_pr_FUNC_NEVER_RETURNS	PARAMS ((cpp_reader *));
+extern void c4x_pr_INTERRUPT		PARAMS ((cpp_reader *));
+extern void c4x_pr_ignored		PARAMS ((cpp_reader *));
+#endif
+
+#endif
===================================================================
Index: config/c4x/c4x.c
--- config/c4x/c4x.c	2000/08/04 23:43:22	1.65
+++ config/c4x/c4x.c	2000/09/07 17:00:30
@@ -45,6 +45,9 @@
 #include "recog.h"
 #include "c-tree.h"
 #include "ggc.h"
+#include "cpplib.h"
+#include "c-lex.h"
+#include "c-pragma.h"
 #include "c4x-protos.h"
 
 rtx smulhi3_libfunc;
@@ -182,6 +185,7 @@ static int c4x_valid_operands PARAMS ((e
 static int c4x_arn_reg_operand PARAMS ((rtx, enum machine_mode, unsigned int));
 static int c4x_arn_mem_operand PARAMS ((rtx, enum machine_mode, unsigned int));
 static void c4x_check_attribute PARAMS ((const char *, tree, tree, tree *));
+static int c4x_parse_pragma PARAMS ((const char *, tree *, tree *));
 
 /* Called to register all of our global variables with the garbage
    collector.  */
@@ -287,7 +291,7 @@ c4x_override_options ()
 
 void
 c4x_optimization_options (level, size)
-     int level;
+     int level ATTRIBUTE_UNUSED;
      int size ATTRIBUTE_UNUSED;
 {
   /* Scheduling before register allocation can screw up global
@@ -4383,123 +4387,112 @@ c4x_operand_subword (op, i, validate_add
 
    */
 
-int
-c4x_handle_pragma (p_getc, p_ungetc, pname)
-     int (* p_getc) PARAMS ((void));
-     void (* p_ungetc) PARAMS ((int)) ATTRIBUTE_UNUSED;
-     char *pname;
+/* Parse a C4x pragma, of the form ( function [, "section"] ) \n.
+   FUNC is loaded with the IDENTIFIER_NODE of the function, SECT with
+   the STRING_CST node of the string.  If SECT is null, then this
+   pragma doesn't take a section string.  Returns 0 for a good pragma,
+   -1 for a malformed pragma.  */
+#define BAD(msgid, arg) do { warning (msgid, arg); return -1; } while (0)
+
+static int
+c4x_parse_pragma (name, func, sect)
+     const char *name;
+     tree *func;
+     tree *sect;
 {
-  int i;
-  int c;
-  int namesize;
-  char *name;
-  tree func;
-  tree sect = NULL_TREE;
-  tree new;
+  tree f, s, x;
 
-  c = p_getc ();
-  while (c == ' ' || c == '\t') c = p_getc ();
-  if (c != '(')
-    return 0;
+  if (c_lex (&x) != CPP_OPEN_PAREN)
+    BAD ("missing '(' after '#pragma %s' - ignored", name);
 
-  c = p_getc ();
-  while (c == ' ' || c == '\t') c = p_getc ();
-  if (! (ISALPHA(c) || c == '_' || c == '$' || c == '@'))
-    return 0;
+  if (c_lex (&f) != CPP_NAME)
+    BAD ("missing function name in '#pragma %s' - ignored", name);
 
-  i = 0;
-  namesize = 16;
-  name = xmalloc (namesize);
-  while (ISALNUM (c) || c == '_' || c == '$' || c == '@')
-    {
-      if (i >= namesize-1)
-	{
-	  namesize += 16;
-	  name = xrealloc (name, namesize);
-	}
-      name[i++] = c;
-      c = p_getc ();
-    }
-  name[i] = 0;
-  func = get_identifier (name);
-  free (name);
-  
-  if (strcmp (pname, "CODE_SECTION") == 0
-      || strcmp (pname, "DATA_SECTION") == 0)
+  if (sect)
     {
-      while (c == ' ' || c == '\t') c = p_getc ();
-      if (c != ',')
-        return 0;
-
-      c = p_getc ();
-      while (c == ' ' || c == '\t') c = p_getc ();
-      if (c != '"')
-        return 0;
-
-      i = 0;
-      namesize = 16;
-      name = xmalloc (namesize);
-      c = p_getc ();
-      while (c != '"' && c != '\n' && c != '\r' && c != EOF)
-        {
-          if (i >= namesize-1)
-	    {
-	      namesize += 16;
-	      name = xrealloc (name, namesize);
-	    }
-          name[i++] = c;
-          c = p_getc ();
-        }
-      name[i] = 0;
-      sect = build_string (i, name);
-      free (name);
-      sect = build_tree_list (NULL_TREE, sect);
-      
-      if (c != '"')
-        return 0;
-      c = p_getc ();
+      if (c_lex (&x) != CPP_COMMA)
+	BAD ("malformed '#pragma %s' - ignored", name);
+      if (c_lex (&s) != CPP_STRING)
+	BAD ("missing section name in '#pragma %s' - ignored", name);
+      *sect = s;
     }
-  while (c == ' ' || c == '\t') c = p_getc ();
-  if (c != ')')
-    return 0;
-  
-  new = build_tree_list (func, sect);
-  if (strcmp (pname, "CODE_SECTION") == 0)
-    code_tree = chainon (code_tree, new);
-  
-  else if (strcmp (pname, "DATA_SECTION") == 0)
-    data_tree = chainon (data_tree, new);
-  
-  else if (strcmp (pname, "FUNC_CANNOT_INLINE") == 0)
-      ; /* Ignore.  */
-  
-  else if (strcmp (pname, "FUNC_EXT_CALLED") == 0)
-      ; /* Ignore.  */
-  
-  else if (strcmp (pname, "FUNC_IS_PURE") == 0)
-     pure_tree = chainon (pure_tree, new);
-  
-  else if (strcmp (pname, "FUNC_IS_SYSTEM") == 0)
-      ; /* Ignore.  */
-  
-  else if (strcmp (pname, "FUNC_NEVER_RETURNS") == 0)
-    noreturn_tree = chainon (noreturn_tree, new);
-  
-  else if (strcmp (pname, "FUNC_NO_GLOBAL_ASG") == 0)
-      ; /* Ignore.  */
-  
-  else if (strcmp (pname, "FUNC_NO_IND_ASG") == 0)
-      ; /* Ignore.  */
-  
-  else if (strcmp (pname, "INTERRUPT") == 0)
-    interrupt_tree = chainon (interrupt_tree, new);
-  
-  else
-    return 0;
-  
-  return 1;
+
+  if (c_lex (&x) != CPP_CLOSE_PAREN)
+    BAD ("missing ')' for '#pragma %s' - ignored", name);
+
+  if (c_lex (&x) != CPP_EOF)
+    warning ("junk at end of '#pragma %s'", name);
+
+  *func = f;
+  return 0;
 }
 
+void
+c4x_pr_CODE_SECTION (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree func, sect;
+
+  if (c4x_parse_pragma ("CODE_SECTION", &func, &sect))
+    return;
+  code_tree = chainon (code_tree,
+		       build_tree_list (func,
+					build_tree_list (NULL_TREE, sect)));
+}
+
+void
+c4x_pr_DATA_SECTION (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree func, sect;
+
+  if (c4x_parse_pragma ("DATA_SECTION", &func, &sect))
+    return;
+  data_tree = chainon (data_tree,
+		       build_tree_list (func,
+					build_tree_list (NULL_TREE, sect)));
+}
+
+void
+c4x_pr_FUNC_IS_PURE (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree func;
+
+  if (c4x_parse_pragma ("FUNC_IS_PURE", &func, 0))
+    return;
+  pure_tree = chainon (pure_tree, build_tree_list (func, NULL_TREE));
+}
+
+void
+c4x_pr_FUNC_NEVER_RETURNS (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree func;
+
+  if (c4x_parse_pragma ("FUNC_NEVER_RETURNS", &func, 0))
+    return;
+  noreturn_tree = chainon (noreturn_tree, build_tree_list (func, NULL_TREE));
+}
+
+void
+c4x_pr_INTERRUPT (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree func;
+
+  if (c4x_parse_pragma ("INTERRUPT", &func, 0))
+    return;
+  interrupt_tree = chainon (interrupt_tree, build_tree_list (func, NULL_TREE));
+}
+
+/* Used for FUNC_CANNOT_INLINE, FUNC_EXT_CALLED, FUNC_IS_SYSTEM,
+   FUNC_NO_GLOBAL_ASG, and FUNC_NO_IND_ASG.  */
+void
+c4x_pr_ignored (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+}
 
 struct name_list
 {
===================================================================
Index: config/c4x/c4x.h
--- config/c4x/c4x.h	2000/07/30 09:12:45	1.56
+++ config/c4x/c4x.h	2000/09/07 17:00:31
@@ -2372,14 +2372,20 @@ asm_fprintf (FILE, "%s%d:\n", PREFIX, NU
 
 #define PRINT_OPERAND_ADDRESS(FILE, X) c4x_print_operand_address(FILE, X)
 
-/* Define this macro if you want to implement any pragmas.  If defined, it
-   should be a C expression to be executed when #pragma is seen.  The
-   argument STREAM is the stdio input stream from which the source
-   text can be read.  CH is the first character after the #pragma.  The
-   result of the expression is the terminating character found
-   (newline or EOF).  */
-#define HANDLE_PRAGMA(GETC, UNGETC, NAME) \
-  c4x_handle_pragma (GETC, UNGETC, NAME)
+/* C4x specific pragmas.  */
+#define REGISTER_TARGET_PRAGMAS(PFILE) do {				\
+  cpp_register_pragma (PFILE, 0, "CODE_SECTION", c4x_pr_CODE_SECTION);	\
+  cpp_register_pragma (PFILE, 0, "DATA_SECTION", c4x_pr_DATA_SECTION);	\
+  cpp_register_pragma (PFILE, 0, "FUNC_CANNOT_INLINE", c4x_pr_ignored);	\
+  cpp_register_pragma (PFILE, 0, "FUNC_EXT_CALLED", c4x_pr_ignored);	\
+  cpp_register_pragma (PFILE, 0, "FUNC_IS_PURE", c4x_pr_FUNC_IS_PURE);	\
+  cpp_register_pragma (PFILE, 0, "FUNC_IS_SYSTEM", c4x_pr_ignored);	\
+  cpp_register_pragma (PFILE, 0, "FUNC_NEVER_RETURNS",			\
+		       c4x_pr_FUNC_NEVER_RETURNS);			\
+  cpp_register_pragma (PFILE, 0, "FUNC_NO_GLOBAL_ASG", c4x_pr_ignored);	\
+  cpp_register_pragma (PFILE, 0, "FUNC_NO_IND_ASG", c4x_pr_ignored);	\
+  cpp_register_pragma (PFILE, 0, "INTERRUPT", c4x_pr_INTERRUPT);	\
+} while (0)
 
 #define SET_DEFAULT_DECL_ATTRIBUTES(DECL, ATTRIBUTES) \
   c4x_set_default_attributes (DECL, &ATTRIBUTES)
===================================================================
Index: config/d30v/d30v.h
--- config/d30v/d30v.h	2000/08/19 22:32:11	1.6
+++ config/d30v/d30v.h	2000/09/07 17:00:33
@@ -19,6 +19,8 @@
    the Free Software Foundation, 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#ifndef GCC_D30V_H
+
 /* D30V specific macros */
 
 /* Align an address */
@@ -5955,15 +5957,6 @@ fprintf (STREAM, "\t.word .L%d\n", VALUE
    is to pretend that the file's contents are enclosed in `extern "C" {...}'.  */
 /* #define NO_IMPLICIT_EXTERN_C */
 
-/* Define this macro if you want to implement any pragmas.  If defined, it
-   should be a C statement to be executed when `#pragma' is seen.  The argument
-   STREAM is the stdio input stream from which the source text can be read.
-
-   It is generally a bad idea to implement new uses of `#pragma'.  The only
-   reason to define this macro is for compatibility with other compilers that
-   do support `#pragma' for the sake of any user programs which already use it.  */
-/* #define HANDLE_PRAGMA(STREAM) */
-
 /* Define this macro to handle System V style pragmas (particularly #pack).
 
    Defined in svr4.h.  */
@@ -6081,3 +6074,5 @@ extern const char *d30v_cond_exec_string
 
 /* Indicate how many instructions can be issued at the same time.  */
 #define ISSUE_RATE 2
+
+#endif /* GCC_D30V_H */
===================================================================
Index: config/h8300/h8300-protos.h
--- config/h8300/h8300-protos.h	2000/08/11 01:43:47	1.4
+++ config/h8300/h8300-protos.h	2000/09/07 17:00:33
@@ -21,6 +21,9 @@ along with GNU CC; see the file COPYING.
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#ifndef GCC_H8300_PROTOS_H
+#define GCC_H8300_PROTOS_H
+
 /* Declarations for functions used in insn-output.c.  */
 #ifdef RTX_CODE
 extern const char *emit_a_shift PARAMS ((rtx, rtx *));
@@ -66,7 +69,6 @@ extern int h8300_tiny_data_p PARAMS ((tr
 extern void h8300_encode_label PARAMS ((tree));
 #endif /* TREE_CODE */
 
-extern int handle_pragma PARAMS ((int (*)(void), void (*)(int), const char *));
 extern void h8300_init_once PARAMS ((void));
 extern void function_prologue PARAMS ((FILE *, int));
 extern void function_epilogue PARAMS ((FILE *, int));
@@ -75,3 +77,10 @@ extern void asm_file_end PARAMS ((FILE *
 extern int ok_for_bclr PARAMS ((HOST_WIDE_INT));
 extern int small_power_of_two PARAMS ((HOST_WIDE_INT));
 extern int initial_offset PARAMS ((int, int));
+
+#ifdef _C_PRAGMA_H
+extern void h8300_pr_interrupt PARAMS ((cpp_reader *));
+extern void h8300_pr_saveall PARAMS ((cpp_reader *));
+#endif
+
+#endif /* GCC_H8300_PROTOS_H */
===================================================================
Index: config/h8300/h8300.c
--- config/h8300/h8300.c	2000/08/14 14:45:30	1.41
+++ config/h8300/h8300.c	2000/09/07 17:00:33
@@ -39,6 +39,7 @@ Boston, MA 02111-1307, USA.  */
 #include "function.h"
 #include "obstack.h"
 #include "toplev.h"
+#include "c-pragma.h"
 #include "tm_p.h"
 
 /* Forward declarations.  */
@@ -730,22 +731,20 @@ eq_operator (x, mode)
    an rte instruction rather than an rts.  A pointer to a function
    with this attribute may be safely used in an interrupt vector.  */
 
-int
-handle_pragma (p_getc, p_ungetc, pname)
-     int (* ATTRIBUTE_UNUSED p_getc) PARAMS ((void));
-     void (* ATTRIBUTE_UNUSED p_ungetc) PARAMS ((int));
-     const char *pname;
-{
-  int retval = 0;
-
-  if (strcmp (pname, "interrupt") == 0)
-    interrupt_handler = retval = 1;
-  else if (strcmp (pname, "saveall") == 0)
-    pragma_saveall = retval = 1;
+void
+h8300_pr_interrupt (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  interrupt_handler = 1;
+}
 
-  return retval;
+void
+h8300_pr_saveall (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  pragma_saveall = 1;
 }
-
+
 /* If the next arg with MODE and TYPE is to be passed in a register, return
    the rtx to represent where it is passed.  CUM represents the state after
    the last argument.  NAMED is not used.  */
===================================================================
Index: config/h8300/h8300.h
--- config/h8300/h8300.h	2000/08/14 14:45:30	1.31
+++ config/h8300/h8300.h	2000/09/07 17:00:34
@@ -22,6 +22,9 @@ along with GNU CC; see the file COPYING.
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#ifndef GCC_H8300_H
+#define GCC_H8300_H
+
 /* Which CPU to compile for.
    We use int for CPU_TYPE to avoid lots of casts.  */
 #if 0 /* defined in insn-attr.h, here for documentation */
@@ -1410,18 +1413,11 @@ do { char dstr[30];					\
 
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
 
-/* Define this macro if you want to implement any pragmas.  If defined, it
-   should be a C expression to be executed when #pragma is seen.  The
-   argument GETC is a function which will return the next character in the
-   input stream, or EOF if no characters are left.  The argument UNGETC is
-   a function which will push a character back into the input stream.  The
-   argument NAME is the word following #pragma in the input stream.  The input
-   stream pointer will be pointing just beyond the end of this word.  The
-   expression should return true if it handled the pragma, false otherwise.
-   The input stream should be left undistrubed if false is returned, otherwise
-   it should be pointing at the last character after the end of the pragma
-   (newline or end-of-file).  */
-#define HANDLE_PRAGMA(GETC, UNGETC, NAME) handle_pragma (GETC, UNGETC, NAME)
+/* H8300 specific pragmas.  */
+#define REGISTER_TARGET_PRAGMAS(PFILE) do {				\
+  cpp_register_pragma (PFILE, 0, "saveall", h8300_pr_saveall);		\
+  cpp_register_pragma (PFILE, 0, "interrupt", h8300_pr_interrupt);	\
+} while (0)
 
 #define FINAL_PRESCAN_INSN(insn, operand, nop) final_prescan_insn (insn, operand,nop)
 
@@ -1454,3 +1450,5 @@ do { char dstr[30];					\
   } while (0)
 
 #define MOVE_RATIO 3
+
+#endif /* GCC_H8300_H */
===================================================================
Index: config/i370/i370-protos.h
--- config/i370/i370-protos.h	2000/01/19 22:25:21	1.1
+++ config/i370/i370-protos.h	2000/09/07 17:00:34
@@ -21,6 +21,9 @@ along with GNU CC; see the file COPYING.
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#ifndef GCC_I370_PROTOS_H
+#define GCC_I370_PROTOS_H
+
 #ifdef RTX_CODE
 extern int i370_branch_dest PARAMS ((rtx));
 extern int i370_branch_length PARAMS ((rtx));
@@ -46,3 +49,9 @@ extern int mvs_check_alias PARAMS ((cons
 extern void i370_function_prolog PARAMS ((FILE *, int));
 extern void check_label_emit PARAMS ((void));
 extern void mvs_free_label_list PARAMS ((void));
+
+#ifdef _C_PRAGMA_H
+extern void i370_pr_map PARAMS ((cpp_reader *));
+#endif
+
+#endif
===================================================================
Index: config/i370/i370.c
--- config/i370/i370.c	2000/07/28 02:17:25	1.13
+++ config/i370/i370.c	2000/09/07 17:00:34
@@ -38,6 +38,9 @@ Boston, MA 02111-1307, USA.  */
 #include "flags.h"
 #include "recog.h"
 #include "toplev.h"
+#include "cpplib.h"
+#include "c-pragma.h"
+#include "c-lex.h"
 #include "tm_p.h"
 
 extern FILE *asm_out_file;
@@ -862,6 +865,17 @@ mvs_add_alias (realname, aliasname, emit
   alias_node_t *ap;
 
   ap = (alias_node_t *) xmalloc (sizeof (alias_node_t));
+  if (strlen (realname) > MAX_LONG_LABEL_SIZE)
+    {
+      warning ("real name is too long - alias ignored");
+      return;
+    }
+  if (strlen (aliasname) > MAX_MVS_LABEL_SIZE)
+    {
+      warning ("alias name is too long - alias ignored");
+      return;
+    }
+      
   strcpy (ap->real_name, realname);
   strcpy (ap->alias_name, aliasname);
   ap->alias_emitted = emitted;
@@ -1005,116 +1019,31 @@ mvs_check_alias (realname, aliasname)
   return 0;
 }
 
-/* Called from check_newline via the macro HANDLE_PRAGMA.
-   p_getc is a pointer to get character routine.
-   p_ungetc is a pointer to un-get character routine.
-   pname is the pointer to the name of the pragma to process.
-   The result is 1 if the pragma was handled.  */
+/* #pragma map (name, alias) -
+   In this implementation both name and alias are required to be
+   identifiers.  The older code seemed to be more permissive.  Can
+   anyone clarify?  */
 
-int
-handle_pragma (p_getc, p_ungetc, pname)
-     int (* p_getc) PARAMS ((void));
-     void (* p_ungetc) PARAMS ((int));
-     const char *pname;
+void
+i370_pr_map (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
 {
-  int retval = 0;
-  register int c;
+  tree name, alias, x;
 
-  if (strcmp (pname, "map") == 0)
+  if (c_lex (&x)        == CPP_OPEN_PAREN
+      && c_lex (&name)  == CPP_NAME
+      && c_lex (&x)     == CPP_COMMA
+      && c_lex (&alias) == CPP_NAME
+      && c_lex (&x)     == CPP_CLOSE_PAREN)
     {
-      char realname[MAX_LONG_LABEL_SIZE + 1];
-      char aliasname[MAX_MVS_LABEL_SIZE + 1];
-      char *s;
+      if (c_lex (&x) != CPP_EOF)
+	warning ("junk at end of #pragma map");
 
-      do {
-	c = p_getc ();
-      } while (c == ' ' || c == '\t');
-
-      if (c == '(')
-        {
-	  s = realname;
-	  do {
-	    c = p_getc ();
-	  } while (c == ' ' || c == '\t');
-	  if (c == '\n')
-	    goto PRAGMA_WARNING;
-	  do {
-	    *s++ = c;
-	    c = p_getc ();
-	  } while (ISALNUM(c) || c == '_');
-	  if (c == '\n')
-	    goto PRAGMA_WARNING;
-	  *s = 0;
-
-	  if (c == ' ' || c == '\t')
-	    do {
-	      c = p_getc ();
-	    } while (c == ' ' || c == '\t');
-	  
-	  if (c == ',')
-	    {
-	      do {
-	        c = p_getc ();
-	      } while (c == ' ' || c == '\t');
-	      if (c == '"')
-	        {
-	          s = aliasname;
-	          c = p_getc ();
-	          do {
-	            if (c == '\\')
-	              {
-	                int d = 0;
-	                do {
-	                  c = p_getc ();
-	                  if (c >= '0' && c <= '7')
-	                      d = (d << 3) | (c - '0');
-	                } while (c >= '0' && c <= '7');
-	                p_ungetc (c);
-	                c = d;
-	                if (d < 1 || d > 255)
-			  warning ("Escape value out of range");
-#ifndef HOST_EBCDIC
-                        c = ebcasc[c];
-#endif
-	              }
-	            *s++ = c;
-	            c = p_getc ();
-	            if (ISSPACE(c) || c == ')')
-	              goto PRAGMA_WARNING;
-	          } while (c != '"');
-	          *s = 0;
-		  if (strlen (aliasname) > MAX_MVS_LABEL_SIZE)
-		    {
-		      warning ("#pragma map alias is too long, truncated");
-		      aliasname[MAX_MVS_LABEL_SIZE] = '\0';
-		    }
-		  do {
-		    c = p_getc ();
-		  } while (c == ' ' || c == '\t');
-		  if (c == ')')
-		    {
-	              mvs_add_alias (realname, aliasname, 1);
-		      retval = 1;
-		    }
-	          else
-	            goto PRAGMA_WARNING;
-	        }
-	      else
-	        goto PRAGMA_WARNING;
-	    }
-	  else
-	    goto PRAGMA_WARNING;
-	  
-        }
-      else
-        {
-	 PRAGMA_WARNING:
-	  warning ("#pragma map options are missing or incorrect");
-        }
-      
+      mvs_add_alias (IDENTIFIER_POINTER (name), IDENTIFIER_POINTER (alias), 1);
+      return;
     }
 
-  return retval;
+  warning ("malformed #pragma map, ignored");
 }
 
 /* defines and functions specific to the HLASM assembler */
===================================================================
Index: config/i370/i370.h
--- config/i370/i370.h	2000/06/27 02:26:19	1.23
+++ config/i370/i370.h	2000/09/07 17:00:34
@@ -147,14 +147,9 @@ extern int mvs_function_name_length;
 #endif
 
 #ifdef TARGET_HLASM
-/* Define this macro if you want to implement any pragmas.  If defined, it
-   is a C expression to be executed when #pragma is seen.  The
-   argument FILE is the stdio input stream from which the source
-   text can be read.  CH is the first character after the #pragma.  The
-   result of the expression is the terminating character found
-   (newline or EOF).  */
-#define HANDLE_PRAGMA(GETC, UNGETC, NAME) \
-  handle_pragma ((GETC), (UNGETC), (NAME))
+/* HLASM requires #pragma map.  */
+#define REGISTER_TARGET_PRAGMAS(PFILE) \
+  cpp_register_pragma (PFILE, 0, "map", i370_pr_map)
 #endif /* TARGET_HLASM */
 
 /* Define maximum length of page minus page escape overhead.  */
===================================================================
Index: config/i370/i370.md
--- config/i370/i370.md	2000/07/27 01:55:55	1.12
+++ config/i370/i370.md	2000/09/07 17:00:35
@@ -2714,7 +2714,6 @@ check_label_emit ();
 {
   rtx dr = gen_reg_rtx (DImode);
   rtx dr_0 = gen_rtx_SUBREG (SImode, dr, 0);
-  rtx dr_1 = gen_rtx_SUBREG (SImode, dr, 1);
 
   emit_insn (gen_rtx_SET (VOIDmode, dr_0, operands[1]));
 
@@ -4717,7 +4716,7 @@ check_label_emit ();
 {
   int i;
 
-  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
+  emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx));
 
   for (i = 0; i < XVECLEN (operands[2], 0); i++)
     {
===================================================================
Index: config/i960/i960-protos.h
--- config/i960/i960-protos.h	2000/01/10 23:22:37	1.1
+++ config/i960/i960-protos.h	2000/09/07 17:00:35
@@ -22,6 +22,9 @@ along with GNU CC; see the file COPYING.
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#ifndef GCC_I960_PROTOS_H
+#define GCC_I960_PROTOS_H
+
 #ifdef RTX_CODE
 extern struct rtx_def *legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
 /* Define the function that build the compare insn for scc and bcc.  */
@@ -102,3 +105,10 @@ extern void i960_function_prologue PARAM
 extern void output_function_profiler PARAMS ((FILE *, int));
 extern void i960_function_epilogue PARAMS ((FILE *, unsigned int));
 extern void i960_scan_opcode PARAMS ((const char *));
+
+#ifdef _C_PRAGMA_H
+extern void i960_pr_align PARAMS ((cpp_reader *));
+extern void i960_pr_noalign PARAMS ((cpp_reader *));
+#endif
+
+#endif /* i960-protos.h */
===================================================================
Index: config/i960/i960.c
--- config/i960/i960.c	2000/06/01 16:29:09	1.18
+++ config/i960/i960.c	2000/09/07 17:00:35
@@ -42,6 +42,9 @@ Boston, MA 02111-1307, USA.  */
 #include "function.h"
 #include "recog.h"
 #include "toplev.h"
+#include "cpplib.h"
+#include "c-pragma.h"
+#include "c-lex.h"
 #include "tm_p.h"
 
 /* Save the operands last given to a compare for use when we
@@ -88,9 +91,87 @@ static int ret_label = 0;
 
 /* Handle pragmas for compatibility with Intel's compilers.  */
 
-/* ??? This is incomplete, since it does not handle all pragmas that the
-   intel compilers understand.  */
+/* NOTE: ic960 R3.0 pragma align definition:
 
+   #pragma align [(size)] | (identifier=size[,...])
+   #pragma noalign [(identifier)[,...]]
+     
+   (all parens are optional)
+     
+   - size is [1,2,4,8,16]
+   - noalign means size==1
+   - applies only to component elements of a struct (and union?)
+   - identifier applies to structure tag (only)
+   - missing identifier means next struct
+     
+   - alignment rules for bitfields need more investigation.
+
+   This implementation only handles the case of no identifiers.  */
+
+void
+i960_pr_align (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree number;
+  enum cpp_ttype type;
+  int align;
+
+  type = c_lex (&number);
+  if (type == CPP_OPEN_PAREN)
+    type = c_lex (&number);
+  if (type == CPP_NAME)
+    {
+      warning ("sorry, not implemented: #pragma align NAME=SIZE");
+      return;
+    }
+  if (type != CPP_NUMBER)
+    {
+      warning ("malformed #pragma align - ignored");
+      return;
+    }
+
+  align = TREE_INT_CST_LOW (number);
+  switch (align)
+    {
+    case 0:
+      /* Return to last alignment.  */
+      align = i960_last_maxbitalignment / 8;
+      /* Fall through.  */
+    case 16:
+    case 8:
+    case 4:
+    case 2:
+    case 1:
+      i960_last_maxbitalignment = i960_maxbitalignment;
+      i960_maxbitalignment = align * 8;
+      break;
+      
+    default:
+      /* Silently ignore bad values.  */
+      break;
+    }
+}
+
+void
+i960_pr_noalign (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  enum cpp_ttype type;
+  tree number;
+
+  type = c_lex (&number);
+  if (type == CPP_OPEN_PAREN)
+    type = c_lex (&number);
+  if (type == CPP_NAME)
+    {
+      warning ("sorry, not implemented: #pragma noalign NAME");
+      return;
+    }
+
+  i960_last_maxbitalignment = i960_maxbitalignment;
+  i960_maxbitalignment = 8;
+}
+
 int
 process_pragma (p_getc, p_ungetc, pname)
      int (*  p_getc) PARAMS ((void));
@@ -132,40 +213,7 @@ process_pragma (p_getc, p_ungetc, pname)
 
   align = atoi (buf);
 
-  switch (align)
-    {
-    case 0:
-      /* Return to last alignment.  */
-      align = i960_last_maxbitalignment / 8;
-      /* Fall through.  */
-    case 16:
-    case 8:
-    case 4:
-    case 2:
-    case 1:
-      i960_last_maxbitalignment = i960_maxbitalignment;
-      i960_maxbitalignment = align * 8;
-      break;
-      
-    default:
-      /* Silently ignore bad values.  */
-      break;
-    }
   
-  /* NOTE: ic960 R3.0 pragma align definition:
-     
-     #pragma align [(size)] | (identifier=size[,...])
-     #pragma noalign [(identifier)[,...]]
-     
-     (all parens are optional)
-     
-     - size is [1,2,4,8,16]
-     - noalign means size==1
-     - applies only to component elements of a struct (and union?)
-     - identifier applies to structure tag (only)
-     - missing identifier means next struct
-     
-     - alignment rules for bitfields need more investigation  */
   
   return 1;
 }
===================================================================
Index: config/i960/i960.h
--- config/i960/i960.h	2000/06/27 02:26:21	1.35
+++ config/i960/i960.h	2000/09/07 17:00:36
@@ -131,7 +131,10 @@ Boston, MA 02111-1307, USA.  */
   fprintf (asm_out_file, "\t.type\t0x%x;", A)
 
 /* Handle pragmas for compatibility with Intel's compilers.  */
-#define HANDLE_PRAGMA(GET, UNGET, NAME) process_pragma (GET, UNGET, NAME)
+#define REGISTER_TARGET_PRAGMAS(PFILE) do {			\
+  cpp_register_pragma (PFILE, 0, "align", i960_pr_align);	\
+  cpp_register_pragma (PFILE, 0, "noalign", i960_pr_noalign);	\
+} while (0)
 
 /* Run-time compilation parameters selecting different hardware subsets.  */
 
===================================================================
Index: config/sh/elf.h
--- config/sh/elf.h	2000/09/02 03:28:47	1.10
+++ config/sh/elf.h	2000/09/07 17:00:36
@@ -112,10 +112,6 @@ do {									\
   fprintf ((FILE), "\t.stabs \"\",%d,0,0,Letext\nLetext:\n", N_SO);	\
 } while (0)
 
-/* HANDLE_SYSV_PRAGMA (defined by svr4.h) takes precedence over HANDLE_PRAGMA.
-   We want to use the HANDLE_PRAGMA from sh.h.  */
-#undef HANDLE_SYSV_PRAGMA
-
 #undef STARTFILE_SPEC
 #define STARTFILE_SPEC \
   "%{!shared: crt1.o%s} crti.o%s \
===================================================================
Index: config/sh/sh-protos.h
--- config/sh/sh-protos.h	2000/09/06 09:20:38	1.8
+++ config/sh/sh-protos.h	2000/09/07 17:00:36
@@ -21,6 +21,9 @@ along with GNU CC; see the file COPYING.
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#ifndef GCC_SH_PROTOS_H
+#define GCC_SH_PROTOS_H
+
 #ifdef RTX_CODE
 extern struct rtx_def *sh_builtin_saveregs PARAMS ((void));
 extern struct rtx_def *prepare_scc_operands PARAMS ((enum rtx_code));
@@ -122,3 +125,11 @@ extern int fldi_ok PARAMS ((void));
 #ifdef HARD_CONST
 extern void fpscr_set_from_mem PARAMS ((int, HARD_REG_SET));
 #endif
+
+#ifdef _C_PRAGMA_H
+extern void sh_pr_interrupt PARAMS ((cpp_reader *));
+extern void sh_pr_trapa PARAMS ((cpp_reader *));
+extern void sh_pr_nosave_low_regs PARAMS ((cpp_reader *));
+#endif
+
+#endif /* sh-protos.h */
===================================================================
Index: config/sh/sh.c
--- config/sh/sh.c	2000/09/06 09:20:38	1.61
+++ config/sh/sh.c	2000/09/07 17:00:37
@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA.  */
 #include "insn-attr.h"
 #include "toplev.h"
 #include "recog.h"
+#include "c-pragma.h"
 #include "tm_p.h"
 
 int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;
@@ -4443,22 +4444,25 @@ initial_elimination_offset (from, to)
 /* Handle machine specific pragmas to be semi-compatible with Hitachi
    compiler.  */
 
-int
-sh_handle_pragma (p_getc, p_ungetc, pname)
-     int (*  p_getc)   PARAMS ((void)) ATTRIBUTE_UNUSED;
-     void (* p_ungetc) PARAMS ((int)) ATTRIBUTE_UNUSED;
-     const char * pname;
-{
-  int retval = 0;
-
-  if (strcmp (pname, "interrupt") == 0)
-    pragma_interrupt = retval = 1;
-  else if (strcmp (pname, "trapa") == 0)
-    pragma_interrupt = pragma_trapa = retval = 1;
-  else if (strcmp (pname, "nosave_low_regs") == 0)
-    pragma_nosave_low_regs = retval = 1;
+void
+sh_pr_interrupt (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  pragma_interrupt = 1;
+}
+
+void
+sh_pr_trapa (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  pragma_interrupt = pragma_trapa = 1;
+}
 
-  return retval;
+void
+sh_pr_nosave_low_regs (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  pragma_nosave_low_regs = 1;
 }
 
 /* Generate 'handle_interrupt' attribute for decls */
===================================================================
Index: config/sh/sh.h
--- config/sh/sh.h	2000/09/07 04:38:34	1.71
+++ config/sh/sh.h	2000/09/07 17:00:38
@@ -21,6 +21,8 @@ along with GNU CC; see the file COPYING.
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#ifndef GCC_SH_H
+#define GCC_SH_H
 
 #define TARGET_VERSION \
   fputs (" (Hitachi SH)", stderr);
@@ -2185,10 +2187,12 @@ extern enum mdep_reorg_phase_e mdep_reor
 
 #define TARGET_MEM_FUNCTIONS
 
-/* Define this macro if you want to implement any pragmas.  If defined, it
-   is a C expression whose value is 1 if the pragma was handled by the
-   macro, zero otherwise.  */
-#define HANDLE_PRAGMA(GETC, UNGETC, NODE) sh_handle_pragma (GETC, UNGETC, NODE)
+/* Handle Hitachi compiler's pragmas.  */
+#define REGISTER_TARGET_PRAGMAS(PFILE) do {				    \
+  cpp_register_pragma (PFILE, 0, "interrupt", sh_pr_interrupt);		    \
+  cpp_register_pragma (PFILE, 0, "trapa", sh_pr_trapa);			    \
+  cpp_register_pragma (PFILE, 0, "nosave_low_regs", sh_pr_nosave_low_regs); \
+} while (0)
 
 /* Set when processing a function with pragma interrupt turned on.  */
 
@@ -2369,3 +2373,5 @@ do {									\
 0:	.p2align 2\n\
 1:	.long	" USER_LABEL_PREFIX #func " - 0b\n\
 2:")
+
+#endif /* sh.h */
===================================================================
Index: config/v850/v850-protos.h
--- config/v850/v850-protos.h	2000/01/19 23:44:14	1.3
+++ config/v850/v850-protos.h	2000/09/07 17:00:38
@@ -20,6 +20,9 @@ Boston, MA 02111-1307, USA.  */
 
 /* Function prototypes that cannot exist in v850.h due to dependency
    compilcations.  */
+#ifndef GCC_V850_PROTOS_H
+#define GCC_V850_PROTOS_H
+
 #define Mmode enum machine_mode
 
 extern void   expand_prologue               PARAMS ((void));
@@ -41,8 +44,8 @@ extern int    compute_frame_size        
 extern void   print_operand                 PARAMS ((FILE *, rtx, int ));
 extern void   print_operand_address         PARAMS ((FILE *, rtx));
 extern int    const_costs                   PARAMS ((rtx, enum rtx_code));
-extern char * output_move_double            PARAMS ((rtx *));
-extern char * output_move_single            PARAMS ((rtx *));
+extern const char *output_move_double       PARAMS ((rtx *));
+extern const char *output_move_single       PARAMS ((rtx *));
 extern void   v850_reorg                    PARAMS ((rtx));
 extern void   notice_update_cc              PARAMS ((rtx, rtx));
 extern char * construct_save_jarl           PARAMS ((rtx));
@@ -80,5 +83,17 @@ extern int    function_arg_partial_nregs
 #endif
 #endif
 
+#ifdef _C_PRAGMA_H
+extern void ghs_pragma_section		    PARAMS ((cpp_reader *));
+extern void ghs_pragma_interrupt	    PARAMS ((cpp_reader *));
+extern void ghs_pragma_starttda		    PARAMS ((cpp_reader *));
+extern void ghs_pragma_startsda		    PARAMS ((cpp_reader *));
+extern void ghs_pragma_startzda		    PARAMS ((cpp_reader *));
+extern void ghs_pragma_endtda		    PARAMS ((cpp_reader *));
+extern void ghs_pragma_endsda		    PARAMS ((cpp_reader *));
+extern void ghs_pragma_endzda		    PARAMS ((cpp_reader *));
+#endif
+
 #undef  Mmode
 
+#endif /* v850-protos.h */
===================================================================
Index: config/v850/v850.c
--- config/v850/v850.c	2000/03/07 20:39:10	1.30
+++ config/v850/v850.c	2000/09/07 17:00:38
@@ -37,7 +37,10 @@ Boston, MA 02111-1307, USA.  */
 #include "function.h"
 #include "obstack.h"
 #include "toplev.h"
-#include "v850-protos.h"
+#include "cpplib.h"
+#include "c-lex.h"
+#include "c-pragma.h"
+#include "tm_p.h"
 
 #ifndef streq
 #define streq(a,b) (strcmp (a, b) == 0)
@@ -50,7 +53,6 @@ static int  const_costs_int        PARAM
 static void substitute_ep_register PARAMS ((rtx, rtx, int, int, rtx *, rtx *));
 static int  push_data_area         PARAMS ((v850_data_area));
 static int  pop_data_area          PARAMS ((v850_data_area));
-static int  parse_ghs_pragma_token PARAMS ((char *));
 static int  ep_memory_offset       PARAMS ((enum machine_mode, int));
 static int  mark_current_function_as_interrupt PARAMS ((void));
 static void v850_set_data_area     PARAMS ((tree, v850_data_area));
@@ -441,7 +443,7 @@ print_operand (file, x, code)
     case 'Q':
       if (special_symbolref_operand (x, VOIDmode))
         {
-          char* name;
+          const char *name;
 
 	  if (GET_CODE (x) == SYMBOL_REF)
 	    name = XSTR (x, 0);
@@ -667,7 +669,7 @@ print_operand_address (file, addr)
 /* Return appropriate code to load up a 1, 2, or 4 integer/floating
    point value.  */
 
-char *
+const char *
 output_move_single (operands)
      rtx *operands;
 {
@@ -759,7 +761,7 @@ output_move_single (operands)
 /* Return appropriate code to load up an 8 byte integer or
    floating point value */
 
-char *
+const char *
 output_move_double (operands)
     rtx *operands;
 {
@@ -2726,292 +2728,151 @@ mark_current_function_as_interrupt ()
     (name, NULL_TREE, current_function_decl, NULL_TREE);
 }
 
-/* Parse STRING as part of a GHS pragma.
-   Returns 0 if the pragma has been parsed and there was a problem,
-   non-zero in all other cases.  */
-static int
-parse_ghs_pragma_token (string)
-     char * string;
-{
-  static enum v850_pragma_state state = V850_PS_START;
-  static enum v850_pragma_type  type  = V850_PT_UNKNOWN;
-  static v850_data_area         data_area = DATA_AREA_NORMAL;
-  static char *                 data_area_name;
-  static enum GHS_section_kind  GHS_section_kind = GHS_SECTION_KIND_DEFAULT;
+/* Support for GHS pragmata.  */
 
-  /* If the string is NULL then we have reached the end of the
-     #pragma construct.  Make sure that we are in an end state, and
-     then implement the pragma's directive.  */
-  if (string == NULL)
-    {
-      int ret_val = 1;
-      
-      if (state != V850_PS_SHOULD_BE_DONE
-	  && state != V850_PS_MAYBE_COMMA
-	  && state != V850_PS_MAYBE_SECTION_NAME)
-	{
-	  if (state != V850_PS_BAD)
-	    warning ("Incomplete #pragma ghs");
+void
+ghs_pragma_section (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  int repeat;
 
-	  ret_val = 0;
-	}
-      else switch (type)
-	{
-	case V850_PT_UNKNOWN:
-	  warning ("Nothing follows #pragma ghs");
-	  ret_val = 0;
-	  break;
-	  
-	case V850_PT_INTERRUPT:
-	  ret_val = mark_current_function_as_interrupt ();
-	  break;
-	  
-	case V850_PT_SECTION:
-	  /* If a section kind has not been specified, then reset
-	     all section names back to their defaults.  */
-	  if (GHS_section_kind == GHS_SECTION_KIND_DEFAULT)
-	    {
-	      int i;
-	      
-	      for (i = COUNT_OF_GHS_SECTION_KINDS; i--;)
-		GHS_current_section_names [i] = NULL;
-	    }
-	  /* If a section has been specified, then this will be handled
-	     by check_default_section_name ().  */
-	  break;
-	  
-	case V850_PT_START_SECTION:
-	  ret_val = push_data_area (data_area);
-	  break;
-	  
-	case V850_PT_END_SECTION:
-	  ret_val = pop_data_area (data_area);
-	  break;
-	}
+  /* #pragma ghs section [name = alias [, name = alias [, ...]]] */
+  do {
+    tree x;
+    enum cpp_ttype type;
+    const char *sect, *alias;
+    enum GHS_section_kind kind;
+
+    type = c_lex (&x);
+    if (type == CPP_EOF && !repeat)
+      goto reset;
+    else if (type == CPP_NAME)
+      sect = IDENTIFIER_POINTER (x);
+    else
+      goto bad;
+    repeat = 0;
+
+    if (c_lex (&x) != CPP_EQ)
+      goto bad;
+    if (c_lex (&x) != CPP_NAME)
+      goto bad;
+    alias = IDENTIFIER_POINTER (x);
+
+    type = c_lex (&x);
+    if (type == CPP_COMMA)
+      repeat = 1;
+    else if (type != CPP_EOF)
+      warning ("junk at end of #pragma ghs section");
+
+    if      (streq (sect, "data"))    kind = GHS_SECTION_KIND_DATA;
+    else if (streq (sect, "text"))    kind = GHS_SECTION_KIND_TEXT;
+    else if (streq (sect, "rodata"))  kind = GHS_SECTION_KIND_RODATA;
+    else if (streq (sect, "const"))   kind = GHS_SECTION_KIND_RODATA;
+    else if (streq (sect, "rosdata")) kind = GHS_SECTION_KIND_ROSDATA;
+    else if (streq (sect, "rozdata")) kind = GHS_SECTION_KIND_ROZDATA;
+    else if (streq (sect, "sdata"))   kind = GHS_SECTION_KIND_SDATA;
+    else if (streq (sect, "tdata"))   kind = GHS_SECTION_KIND_TDATA;
+    else if (streq (sect, "zdata"))   kind = GHS_SECTION_KIND_ZDATA;
+    /* According to GHS beta documentation, the following should not be
+       allowed!  */
+    else if (streq (sect, "bss"))     kind = GHS_SECTION_KIND_BSS;
+    else if (streq (sect, "zbss"))    kind = GHS_SECTION_KIND_ZDATA;
+    else
+      {
+	warning ("unrecognised section name \"%s\"", sect);
+	return;
+      }
 
-      state = V850_PS_START;
-      type  = V850_PT_UNKNOWN;
-      
-      return ret_val;
-    }
-  
-  switch (state)
-    {
-    case V850_PS_START:
-      data_area = DATA_AREA_NORMAL;
-      data_area_name = NULL;
-      
-      if (streq (string, "interrupt"))
-	{
-	  type = V850_PT_INTERRUPT;
-	  state = V850_PS_SHOULD_BE_DONE;
-	}
-      else if (streq (string, "section"))
-	{
-	  type = V850_PT_SECTION;
-	  state = V850_PS_MAYBE_SECTION_NAME;
-	  GHS_section_kind = GHS_SECTION_KIND_DEFAULT;
-	}
-      else if (streq (string, "starttda"))
-	{
-	  type = V850_PT_START_SECTION;
-	  state = V850_PS_SHOULD_BE_DONE;
-	  data_area = DATA_AREA_TDA;
-	}
-      else if (streq (string, "endtda"))
-	{
-	  type = V850_PT_END_SECTION;
-	  state = V850_PS_SHOULD_BE_DONE;
-	  data_area = DATA_AREA_TDA;
-	}
-      else if (streq (string, "startsda"))
-	{
-	  type = V850_PT_START_SECTION;
-	  state = V850_PS_SHOULD_BE_DONE;
-	  data_area = DATA_AREA_SDA;
-	}
-      else if (streq (string, "endsda"))
-	{
-	  type = V850_PT_END_SECTION;
-	  state = V850_PS_SHOULD_BE_DONE;
-	  data_area = DATA_AREA_SDA;
-	}
-      else if (streq (string, "startzda"))
-	{
-	  type = V850_PT_START_SECTION;
-	  state = V850_PS_SHOULD_BE_DONE;
-	  data_area = DATA_AREA_ZDA;
-	}
-      else if (streq (string, "endzda"))
-	{
-	  type = V850_PT_END_SECTION;
-	  state = V850_PS_SHOULD_BE_DONE;
-	  data_area = DATA_AREA_ZDA;
-	}
-      else
-	{
-	  warning ("Unrecognised GHS pragma: '%s'\n", string);
-	  state = V850_PS_BAD;
-	}
-      break;
-      
-    case V850_PS_SHOULD_BE_DONE:
-      warning ("Extra text after valid #pragma: '%s'", string);
-      state = V850_PS_BAD;
-      break;
-      
-    case V850_PS_BAD:
-      /* Ignore tokens in a pragma that has been diagnosed as being corrupt. */
-      break;
+    if (streq (alias, "default"))
+      GHS_current_section_names [kind] = NULL;
+    else
+      GHS_current_section_names [kind] =
+	build_string (strlen (alias) + 1, alias);
+
+  } while (repeat);
+  return;
+
+ bad:
+  warning ("malformed #pragma ghs section");
+  return;
 
-    case V850_PS_MAYBE_SECTION_NAME:
-      state = V850_PS_EXPECTING_EQUALS;
-      
-           if (streq (string, "data"))	  GHS_section_kind = GHS_SECTION_KIND_DATA;
-      else if (streq (string, "text"))	  GHS_section_kind = GHS_SECTION_KIND_TEXT;
-      else if (streq (string, "rodata"))  GHS_section_kind = GHS_SECTION_KIND_RODATA;
-      else if (streq (string, "const"))	  GHS_section_kind = GHS_SECTION_KIND_RODATA;
-      else if (streq (string, "rosdata")) GHS_section_kind = GHS_SECTION_KIND_ROSDATA;
-      else if (streq (string, "rozdata")) GHS_section_kind = GHS_SECTION_KIND_ROZDATA;
-      else if (streq (string, "sdata"))	  GHS_section_kind = GHS_SECTION_KIND_SDATA;
-      else if (streq (string, "tdata"))	  GHS_section_kind = GHS_SECTION_KIND_TDATA;
-      else if (streq (string, "zdata"))	  GHS_section_kind = GHS_SECTION_KIND_ZDATA;
-      /* According to GHS beta documentation, the following should not be allowed!  */
-      else if (streq (string, "bss"))	  GHS_section_kind = GHS_SECTION_KIND_BSS;
-      else if (streq (string, "zbss"))	  GHS_section_kind = GHS_SECTION_KIND_ZDATA;
-      else
-	{
-	  warning ("Unrecognised section name '%s' in GHS section pragma",
-		   string);
-	  state = V850_PS_BAD;
-	}
-      break;
+ reset:
+  /* #pragma ghs section \n: Reset all section names back to their defaults.  */
+  {
+    int i;
+    for (i = COUNT_OF_GHS_SECTION_KINDS; i--;)
+      GHS_current_section_names [i] = NULL;
+  }
+}
 
-    case V850_PS_EXPECTING_EQUALS:
-      if (streq (string, "="))
-	state = V850_PS_EXPECTING_SECTION_ALIAS;
-      else
-	{
-	  warning ("Missing '=' in GHS section pragma");
-	  state = V850_PS_BAD;
-	}
-      break;
-      
-    case V850_PS_EXPECTING_SECTION_ALIAS:
-      if (streq (string, "default"))
-	GHS_current_section_names [GHS_section_kind] = NULL;
-      else
-	GHS_current_section_names [GHS_section_kind] =
-	  build_string (strlen (string) + 1, string);
-      
-      state = V850_PS_MAYBE_COMMA;
-      break;
-      
-    case V850_PS_MAYBE_COMMA:
-      if (streq (string, ","))
-	state = V850_PS_MAYBE_SECTION_NAME;
-      else
-	{
-	  warning
-	    ("Malformed GHS section pragma: found '%s' instead of a comma",
-	     string);
-	  state = V850_PS_BAD;
-	}
-      break;
-    }
-  
-  return 1;
+void
+ghs_pragma_interrupt (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree x;
+  if (c_lex (&x) != CPP_EOF)
+    warning ("junk at end of #pragma ghs interrupt");
+  mark_current_function_as_interrupt ();
 }
 
-/* Handle the parsing of an entire GHS pragma.  */
-int
-v850_handle_pragma (p_getc, p_ungetc, name)
-     int (*  p_getc) PARAMS ((void));
-     void (* p_ungetc) PARAMS ((int));
-     char *  name;
-{
-  /* Parse characters in the input stream until:
-
-   * end of line
-   * end of file
-   * a complete GHS pragma has been parsed
-   * a corrupted GHS pragma has been parsed
-   * an unknown pragma is encountered.
-
-   If an unknown pragma is encountered, we must return with
-   the input stream in the same state as upon entry to this function.
-   
-   The first token in the input stream has already been parsed
-   for us, and is passed as 'name'.  */
-  
-  if (! streq (name, "ghs"))
-    return 0;
+void
+ghs_pragma_starttda (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree x;
+  if (c_lex (&x) != CPP_EOF)
+    warning ("junk at end of #pragma ghs starttda");
+  push_data_area (DATA_AREA_TDA);
+}
 
-  /* We now know that we are parsing a GHS pragma, so we do
-     not need to preserve the original input stream state.  */
-  for (;;)
-    {
-      static char buffer [128];
-      int         c;
-      char *      buff;
-      
-      /* Skip white space.  */
-      do
-	c = p_getc ();
-      while (c == ' ' || c == '\t');
-      
-      p_ungetc (c);
-      
-      if (c == '\n' || c == EOF || c == '\r')
-	return parse_ghs_pragma_token (NULL);
-
-      /* Read next word.  We have to do the parsing ourselves, rather
-	 than calling yylex() because we can be built with front ends
-	 that do not provide such functions.  */
-      buff = buffer;
-      * buff ++ = (c = p_getc ());
-
-      switch (c)
-	{
-	case ',':
-	case '=':
-	  * buff ++ = (c = p_getc ());
-	  break;
-	  
-	case '"':
-	  /* Skip opening double parenthesis.  */
-	  -- buff;
-
-	  /* Read string.  */
-	  do
-	    * buff ++ = (c = p_getc ());
-	  while (c != EOF && (ISALNUM (c) || c == '_' || c == '.' || c == ' ')
-		 && (buff < buffer + 126));
-	  
-	  if (c != '"')
-	    warning ("Missing trailing \" in #pragma ghs");
-	  else
-	    c = p_getc ();
-	  break;
+void
+ghs_pragma_startsda (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree x;
+  if (c_lex (&x) != CPP_EOF)
+    warning ("junk at end of #pragma ghs startsda");
+  push_data_area (DATA_AREA_SDA);
+}
 
-	default:
-	  while (c != EOF && (ISALNUM (c) || c == '_' || c == '.')
-		 && (buff < buffer + 126))
-	    * buff ++ = (c = p_getc ());
-	  break;
-	}
+void
+ghs_pragma_startzda (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree x;
+  if (c_lex (&x) != CPP_EOF)
+    warning ("junk at end of #pragma ghs startzda");
+  push_data_area (DATA_AREA_ZDA);
+}
 
-      p_ungetc (c);
+void
+ghs_pragma_endtda (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree x;
+  if (c_lex (&x) != CPP_EOF)
+    warning ("junk at end of #pragma ghs endtda");
+  pop_data_area (DATA_AREA_TDA);
+}
 
-      /* If nothing was read then terminate the parsing.  */
-      if (buff == buffer + 1)
-	return parse_ghs_pragma_token (NULL);
+void
+ghs_pragma_endsda (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree x;
+  if (c_lex (&x) != CPP_EOF)
+    warning ("junk at end of #pragma ghs endsda");
+  pop_data_area (DATA_AREA_SDA);
+}
 
-      /* Parse and continue.  */
-      * -- buff = 0;
-      
-      parse_ghs_pragma_token (buffer);
-    }
+void
+ghs_pragma_endzda (pfile)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+  tree x;
+  if (c_lex (&x) != CPP_EOF)
+    warning ("junk at end of #pragma ghs endzda");
+  pop_data_area (DATA_AREA_ZDA);
 }
 
 /* Add data area to the given declaration if a ghs data area pragma is
===================================================================
Index: config/v850/v850.h
--- config/v850/v850.h	2000/06/27 02:26:23	1.28
+++ config/v850/v850.h	2000/09/07 17:00:39
@@ -19,6 +19,9 @@ along with GNU CC; see the file COPYING.
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#ifndef GCC_V850_H
+#define GCC_V850_H
+
 #include "svr4.h"	/* Automatically does #undef CPP_PREDEFINES */
 
 /* These are defiend in svr4.h but we want to override them.  */
@@ -138,7 +141,7 @@ extern int target_flags;
 
 /* Information about the various small memory areas.  */
 struct small_memory_info {
-  char *name;
+  const char *name;
   const char *value;
   long max;
   long physical_max;
@@ -1505,27 +1508,17 @@ do { char dstr[30];					\
      v850_set_default_decl_attr (decl)
 
 /* Tell compiler we want to support GHS pragmas */
-#define HANDLE_PRAGMA(get, unget, name) v850_handle_pragma (get, unget, name)
-
-enum v850_pragma_state
-{
-  V850_PS_START,
-  V850_PS_SHOULD_BE_DONE,
-  V850_PS_BAD,
-  V850_PS_MAYBE_SECTION_NAME,
-  V850_PS_EXPECTING_EQUALS,
-  V850_PS_EXPECTING_SECTION_ALIAS,
-  V850_PS_MAYBE_COMMA
-};
-
-enum v850_pragma_type
-{
-  V850_PT_UNKNOWN,
-  V850_PT_INTERRUPT,
-  V850_PT_SECTION,
-  V850_PT_START_SECTION,
-  V850_PT_END_SECTION
-};
+#define REGISTER_TARGET_PRAGMAS(PFILE) do {				  \
+  cpp_register_pragma_space (PFILE, "ghs");				  \
+  cpp_register_pragma (PFILE, "ghs", "interrupt", ghs_pragma_interrupt);  \
+  cpp_register_pragma (PFILE, "ghs", "section",   ghs_pragma_section);    \
+  cpp_register_pragma (PFILE, "ghs", "starttda",  ghs_pragma_starttda);   \
+  cpp_register_pragma (PFILE, "ghs", "startsda",  ghs_pragma_startsda);   \
+  cpp_register_pragma (PFILE, "ghs", "startzda",  ghs_pragma_startzda);   \
+  cpp_register_pragma (PFILE, "ghs", "endtda",    ghs_pragma_endtda);	  \
+  cpp_register_pragma (PFILE, "ghs", "endsda",    ghs_pragma_endsda);	  \
+  cpp_register_pragma (PFILE, "ghs", "endzda",    ghs_pragma_endzda);	  \
+} while (0)
 
 /* enum GHS_SECTION_KIND is an enumeration of the kinds of sections that
    can appear in the "ghs section" pragma.  These names are used to index
@@ -1621,3 +1614,4 @@ enum GHS_section_kind
 { "register_is_ok_for_epilogue",{ REG }},				\
 { "not_power_of_two_operand",	{ CONST_INT }},
   
+#endif /* v850.h */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]