+2000-09-07 Zack Weinberg <zack@wolery.cumb.org>
+
+ * 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.
+
2000-09-07 Kazu Hirata <kazu@hxi.com>
* config/h8300.h: Fix comment typos.
#include "c-tree.h"
#include "flags.h"
#include "timevar.h"
+#include "cpplib.h"
#include "c-pragma.h"
#include "toplev.h"
#include "intl.h"
#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
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
\f
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;
/* 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 */
/* Parse a '\uNNNN' or '\UNNNNNNNN' sequence.
#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"
/* 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
#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
enum cpp_ttype t;
tree x;
const struct pragma_entry *p;
- const char *name;
+ const char *name, *space = 0;
size_t len;
p = pragmas;
{
if (p->isnspace)
{
+ space = p->name;
p = p->u.space;
goto new_space;
}
}
/* 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
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
ggc_add_root (&alignment_stack, 1, sizeof(alignment_stack),
mark_align_stack);
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
# 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 */
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));
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 */
#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"
#include "recog.h"
#include "ggc.h"
#include "except.h"
+#include "c-pragma.h"
#include "tm_p.h"
/* Forward definitions of types. */
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;
+}
+
\f
/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
attribute for TYPE. The attributes in ATTRIBUTES have previously been
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)
-\f
+#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.
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));
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
#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;
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. */
void
c4x_optimization_options (level, size)
- int level;
+ int level ATTRIBUTE_UNUSED;
int size ATTRIBUTE_UNUSED;
{
/* Scheduling before register allocation can screw up global
*/
-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, §))
+ 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, §))
+ 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
{
#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)
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#ifndef GCC_D30V_H
+
/* D30V specific macros */
/* Align an address */
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. */
/* Indicate how many instructions can be issued at the same time. */
#define ISSUE_RATE 2
+
+#endif /* GCC_D30V_H */
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 *));
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));
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 */
#include "function.h"
#include "obstack.h"
#include "toplev.h"
+#include "c-pragma.h"
#include "tm_p.h"
/* Forward declarations. */
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;
+void
+h8300_pr_interrupt (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
{
- int retval = 0;
-
- if (strcmp (pname, "interrupt") == 0)
- interrupt_handler = retval = 1;
- else if (strcmp (pname, "saveall") == 0)
- pragma_saveall = retval = 1;
+ interrupt_handler = 1;
+}
- return retval;
+void
+h8300_pr_saveall (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+ pragma_saveall = 1;
}
-\f
+
/* 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. */
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 */
#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)
} while (0)
#define MOVE_RATIO 3
+
+#endif /* GCC_H8300_H */
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));
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
#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;
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;
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 */
#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. */
{
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]));
{
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++)
{
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. */
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 */
#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
/* 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)
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;
}
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. */
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 \
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));
#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 */
#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;
/* 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;
+void
+sh_pr_interrupt (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
{
- int retval = 0;
+ pragma_interrupt = 1;
+}
- 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_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 */
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);
#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. */
0: .p2align 2\n\
1: .long " USER_LABEL_PREFIX #func " - 0b\n\
2:")
+
+#endif /* sh.h */
/* 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));
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));
#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 */
#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)
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));
case 'Q':
if (special_symbolref_operand (x, VOIDmode))
{
- char* name;
+ const char *name;
if (GET_CODE (x) == SYMBOL_REF)
name = XSTR (x, 0);
/* Return appropriate code to load up a 1, 2, or 4 integer/floating
point value. */
-char *
+const char *
output_move_single (operands)
rtx *operands;
{
/* Return appropriate code to load up an 8 byte integer or
floating point value */
-char *
+const char *
output_move_double (operands)
rtx *operands;
{
(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;
+/* Support for GHS pragmata. */
+
+void
+ghs_pragma_section (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
{
- 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;
-
- /* 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");
+ int repeat;
+
+ /* #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;
+ }
- 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;
- }
+ if (streq (alias, "default"))
+ GHS_current_section_names [kind] = NULL;
+ else
+ GHS_current_section_names [kind] =
+ build_string (strlen (alias) + 1, alias);
- 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;
+ } while (repeat);
+ 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;
+ bad:
+ warning ("malformed #pragma ghs section");
+ return;
- 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;
+ 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;
+ }
}
-/* 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;
+void
+ghs_pragma_interrupt (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
{
- /* 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;
-
- /* 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);
+ tree x;
+ if (c_lex (&x) != CPP_EOF)
+ warning ("junk at end of #pragma ghs interrupt");
+ mark_current_function_as_interrupt ();
+}
- /* 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 ());
+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);
+}
- 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
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. */
/* Information about the various small memory areas. */
struct small_memory_info {
- char *name;
+ const char *name;
const char *value;
long max;
long physical_max;
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
{ "register_is_ok_for_epilogue",{ REG }}, \
{ "not_power_of_two_operand", { CONST_INT }},
+#endif /* v850.h */
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;
@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.
-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.
+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.
+
+For an example use of this routine in a target header, see @file{v850.h}.
+@end deftypefun
@findex HANDLE_SYSV_PRAGMA
@findex #pragma