Index: target.def =================================================================== --- target.def (revision 0) +++ target.def (revision 0) @@ -0,0 +1,263 @@ +/* Target hook definitions. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not see + . + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! */ + +/* The following macros should be provided by the including file: + + DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT): Define a function-valued hook. + DEFHOOKPOD(DOC, TYPE, NAME, INIT): Define a piece-of-data 'hook'. */ + +/* Defaults for optional macros: + DEFHOOKPODX(NAME, NAME, INIT): Like DEFHOOKPOD, but share documentation + with the previous 'hook'. */ +#ifndef DEFHOOKPODX +#define DEFHOOKPODX(NAME, TYPE, INIT) DEFHOOKPOD (NAME, 0, TYPE, INIT) +#endif + +/* HOOKSTRUCT(FRAGMENT): Declarator fragments to encapsulate all the + members into a struct gcc_target, which in turn contains several + sub-structs. */ +#ifndef HOOKSTRUCT +#define HOOKSTRUCT(FRAGMENT) +#endif + +HOOKSTRUCT (struct gcc_target {) + +/* Functions that output assembler for the target. */ +#define HOOK_PREFIX "TARGET_ASM_" +HOOKSTRUCT (struct asm_out {) + +DEFHOOKPOD +(open_paren, +"These target hooks are C string constants, describing the syntax in the\ + assembler for grouping arithmetic expressions. If not overridden, they\ + default to normal parentheses, which is correct for most assemblers.", + const char *, "(") +DEFHOOKPODX (close_paren, const char *, ")") + +DEFHOOKPOD +(byte_op, +"@deftypevrx {Target Hook} {const char *} TARGET_ASM_ALIGNED_HI_OP\n" +"@deftypevrx {Target Hook} {const char *} TARGET_ASM_ALIGNED_SI_OP\n" +"@deftypevrx {Target Hook} {const char *} TARGET_ASM_ALIGNED_DI_OP\n" +"@deftypevrx {Target Hook} {const char *} TARGET_ASM_ALIGNED_TI_OP\n" +"@deftypevrx {Target Hook} {const char *} TARGET_ASM_UNALIGNED_HI_OP\n" +"@deftypevrx {Target Hook} {const char *} TARGET_ASM_UNALIGNED_SI_OP\n" +"@deftypevrx {Target Hook} {const char *} TARGET_ASM_UNALIGNED_DI_OP\n" +"@deftypevrx {Target Hook} {const char *} TARGET_ASM_UNALIGNED_TI_OP\n" +"These hooks specify assembly directives for creating certain kinds\ + of integer object. The @code{TARGET_ASM_BYTE_OP} directive creates a\ + byte-sized object, the @code{TARGET_ASM_ALIGNED_HI_OP} one creates an\ + aligned two-byte object, and so on. Any of the hooks may be\ + @code{NULL}, indicating that no suitable directive is available.\n\n" + +"The compiler will print these strings at the start of a new line,\ + followed immediately by the object's initial value. In most cases,\ + the string should contain a tab, a pseudo-op, and then another tab.", + const char *, "\t.byte\t") +DEFHOOKPOD +(aligned_op, "*", struct asm_int_op, + ({ TARGET_ASM_ALIGNED_HI_OP, TARGET_ASM_ALIGNED_SI_OP, + TARGET_ASM_ALIGNED_DI_OP, TARGET_ASM_ALIGNED_TI_OP }) ) +DEFHOOKPOD +(unaligned_op, "*", struct asm_int_op, + ({ TARGET_ASM_UNALIGNED_HI_OP, TARGET_ASM_UNALIGNED_SI_OP, + TARGET_ASM_UNALIGNED_DI_OP, TARGET_ASM_UNALIGNED_TI_OP }) ) + /* Assembler instructions for creating various kinds of integer object. */ + +DEFHOOK +(integer, +"The @code{assemble_integer} function uses this hook to output an\ + integer object. @var{x} is the object's value, @var{size} is its size\ + in bytes and @var{aligned_p} indicates whether it is aligned. The\ + function should return @code{true} if it was able to output the\ + object. If it returns false, @code{assemble_integer} will try to\ + split the object into smaller parts.\n\n" + +"The default implementation of this hook will use the\ + @code{TARGET_ASM_BYTE_OP} family of strings, returning @code{false}\ + when the relevant string is @code{NULL}.", + /* Only handles cases for which BYTE_OP, ALIGNED_OP and UNALIGNED_OP are + NULL. */ + bool, (rtx x, unsigned int size, int aligned_p), + default_assemble_integer) + +DEFHOOK +(globalize_label, +"This target hook is a function to output to the stdio stream\ + @var{stream} some commands that will make the label @var{name} global;\ + that is, available for reference from other files.\n\n" + +"The default implementation relies on a proper definition of\ + @code{GLOBAL_ASM_OP}.", + void, (FILE *stream, const char *name), + default_globalize_label) + +DEFHOOK +(globalize_decl_name, +"This target hook is a function to output to the stdio stream\ + @var{stream} some commands that will make the name associated with @var{decl}\ + global; that is, available for reference from other files.\n\n" + +"The default implementation uses the TARGET_ASM_GLOBALIZE_LABEL target hook.", + void, (FILE *stream, tree decl), default_globalize_decl_name) + +DEFHOOK +(emit_unwind_label, +"This target hook emits a label at the beginning of each FDE@. It \ + should be defined on targets where FDEs need special labels, and it \ + should write the appropriate label, for the FDE associated with the \ + function declaration @var{decl}, to the stdio stream @var{stream}. \ + The third argument, @var{for_eh}, is a boolean: true if this is for an \ + exception table. The fourth argument, @var{empty}, is a boolean: \ + true if this is a placeholder label for an omitted FDE@.\n\n" + +"The default is that FDEs are not given nonlocal labels.", + void, (FILE *stream, tree decl, int for_eh, int empty), + default_emit_unwind_label) + +#if 0 + /* Output code that will emit a label to divide up the exception + table. */ + void (* except_table_label) (FILE *); + + /* Emit any directives required to unwind this instruction. */ + void (* unwind_emit) (FILE *, rtx); + + /* Output an internal label. */ + void (* internal_label) (FILE *, const char *, unsigned long); + + /* Emit a ttype table reference to a typeinfo object. */ + bool (* ttype) (rtx); + + /* Emit an assembler directive to set visibility for the symbol + associated with the tree decl. */ + void (* visibility) (tree, int); + + /* Output the assembler code for entry to a function. */ + void (* function_prologue) (FILE *, HOST_WIDE_INT); + + /* Output the assembler code for end of prologue. */ + void (* function_end_prologue) (FILE *); + + /* Output the assembler code for start of epilogue. */ + void (* function_begin_epilogue) (FILE *); + + /* Output the assembler code for function exit. */ + void (* function_epilogue) (FILE *, HOST_WIDE_INT); + + /* Initialize target-specific sections. */ + void (* init_sections) (void); + + /* Tell assembler to change to section NAME with attributes FLAGS. + If DECL is non-NULL, it is the VAR_DECL or FUNCTION_DECL with + which this section is associated. */ + void (* named_section) (const char *name, unsigned int flags, tree decl); + + /* Return a mask describing how relocations should be treated when + selecting sections. Bit 1 should be set if global relocations + should be placed in a read-write section; bit 0 should be set if + local relocations should be placed in a read-write section. */ + int (*reloc_rw_mask) (void); + + /* Return a section for EXP. It may be a DECL or a constant. RELOC + is nonzero if runtime relocations must be applied; bit 1 will be + set if the runtime relocations require non-local name resolution. + ALIGN is the required alignment of the data. */ + section *(* select_section) (tree, int, unsigned HOST_WIDE_INT); + + /* Return a section for X. MODE is X's mode and ALIGN is its + alignment in bits. */ + section *(* select_rtx_section) (enum machine_mode, rtx, + unsigned HOST_WIDE_INT); + + /* Select a unique section name for DECL. RELOC is the same as + for SELECT_SECTION. */ + void (* unique_section) (tree, int); + + /* Return the readonly data section associated with function DECL. */ + section *(* function_rodata_section) (tree); + + /* Output a constructor for a symbol with a given priority. */ + void (* constructor) (rtx, int); + + /* Output a destructor for a symbol with a given priority. */ + void (* destructor) (rtx, int); + + /* Output the assembler code for a thunk function. THUNK_DECL is the + declaration for the thunk function itself, FUNCTION is the decl for + the target function. DELTA is an immediate constant offset to be + added to THIS. If VCALL_OFFSET is nonzero, the word at + *(*this + vcall_offset) should be added to THIS. */ + void (* output_mi_thunk) (FILE *file, tree thunk_decl, + HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset, + tree function_decl); + + /* Determine whether output_mi_thunk would succeed. */ + /* ??? Ideally, this hook would not exist, and success or failure + would be returned from output_mi_thunk directly. But there's + too much undo-able setup involved in invoking output_mi_thunk. + Could be fixed by making output_mi_thunk emit rtl instead of + text to the output file. */ + bool (* can_output_mi_thunk) (const_tree thunk_decl, HOST_WIDE_INT delta, + HOST_WIDE_INT vcall_offset, + const_tree function_decl); + + /* Output any boilerplate text needed at the beginning of a + translation unit. */ + void (*file_start) (void); + + /* Output any boilerplate text needed at the end of a + translation unit. */ + void (*file_end) (void); + + /* Output an assembler pseudo-op to declare a library function name + external. */ + void (*external_libcall) (rtx); + + /* Output an assembler directive to mark decl live. This instructs + linker to not dead code strip this symbol. */ + void (*mark_decl_preserved) (const char *); + + /* Output a record of the command line switches that have been passed. */ + print_switch_fn_type record_gcc_switches; + /* The name of the section that the example ELF implementation of + record_gcc_switches will use to store the information. Target + specific versions of record_gcc_switches may or may not use + this information. */ + const char * record_gcc_switches_section; + + /* Output the definition of a section anchor. */ + void (*output_anchor) (rtx); + + /* Output a DTP-relative reference to a TLS symbol. */ + void (*output_dwarf_dtprel) (FILE *file, int size, rtx x); + + /* Some target machines need to postscan each insn after it is output. */ + void (*final_postscan_insn) (FILE *, rtx, rtx *, int); + + /* Emit the trampoline template. This hook may be NULL. */ + void (*trampoline_template) (FILE *); + +HOOKSTRUCT (} asm_out;) + +HOOKSTRUCT (struct sched {) +#endif /* 0 */ Index: target.h =================================================================== --- target.h (revision 155367) +++ target.h (working copy) @@ -108,7 +108,13 @@ struct asm_int_op }; /* The target structure. This holds all the backend hooks. */ +#define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME; +#define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS; +#define HOOKSTRUCT(FRAGMENT) FRAGMENT +#include "target.def" + +#if 0 struct gcc_target { /* Functions that output assembler for the target. */ @@ -141,6 +147,7 @@ struct gcc_target this is only a placeholder for an omitted FDE. */ void (* unwind_label) (FILE *, tree, int, int); +#endif /* 0 */ /* Output code that will emit a label to divide up the exception table. */ void (* except_table_label) (FILE *); Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 155367) +++ dwarf2out.c (working copy) @@ -3457,8 +3457,8 @@ output_fde (dw_fde_ref fde, bool for_eh, char l1[20], l2[20]; dw_cfi_ref cfi; - targetm.asm_out.unwind_label (asm_out_file, fde->decl, for_eh, - /* empty */ 0); + targetm.asm_out.emit_unwind_label (asm_out_file, fde->decl, for_eh, + /* empty */ 0); targetm.asm_out.internal_label (asm_out_file, FDE_LABEL, for_eh + j); ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + j); @@ -3651,8 +3651,8 @@ output_call_frame_info (int for_eh) if ((fde_table[i].nothrow || fde_table[i].all_throwers_are_sibcalls) && !fde_table[i].uses_eh_lsda && ! DECL_WEAK (fde_table[i].decl)) - targetm.asm_out.unwind_label (asm_out_file, fde_table[i].decl, - for_eh, /* empty */ 1); + targetm.asm_out.emit_unwind_label (asm_out_file, fde_table[i].decl, + for_eh, /* empty */ 1); /* If we don't have any functions we'll want to unwind out of, don't emit any EH unwind information. Note that if exceptions aren't Index: gentarget.c =================================================================== --- gentarget.c (revision 0) +++ gentarget.c (revision 0) @@ -0,0 +1,70 @@ +#include "bconfig.h" +#include "system.h" +#include + +struct hook_desc { const char *doc, *type, *name, *param, *init; }; +static struct hook_desc hook_array[] = { +#define DEFHOOKPOD(NAME, DOC, TYPE, INIT) \ + { DOC, #TYPE, HOOK_PREFIX #NAME, 0, #INIT }, +#define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) \ + { DOC, #TYPE, HOOK_PREFIX #NAME, #PARAMS, #INIT }, +#include "target.def" +#undef DEFHOOK +}; + +int +main (int argc, char **argv) +{ + bool doc_p = false; + int i, j; + + if (argc >= 2 && strcmp (argv[1], "-doc") == 0) + doc_p = true; + for (i = 0; i < (int) (sizeof hook_array / sizeof hook_array[0]); i++) + { + char *name = xstrdup (hook_array[i].name); + char *p; + const char *q, *e; + + for (p = name; *p; p++) + *p = TOUPPER (*p); + if (doc_p) + { + const char *deftype; + + if (!hook_array[i].doc) + continue; + if (*hook_array[i].doc == '*') + { + printf ("%s", hook_array[i].doc + 1); + continue; + } + deftype = hook_array[i].param ? "deftypefn" : "deftypevr"; + printf ("@%s {Target Hook} {%s} %s", + deftype, hook_array[i].type, name); + if (hook_array[i].param) + { + /* Print the parameter list, with the parameter names + enclosed in @var{}. */ + printf (" "); + for (q = hook_array[i].param; (e = strpbrk (q, " ,)")); + q = e + 1) + if (*e == ' ') + printf ("%.*s", e - q + 1, q); + else + printf ("@var{%.*s}%c", e - q, q, *e); + } + printf ("\n"); + for (j = i + 1; + j < (int) (sizeof hook_array / sizeof hook_array[0]) + && hook_array[j].doc == 0; j++) + printf ("@%sx {Target Hook} {%s} %s\n", + deftype, hook_array[i].type, name); + printf ("%s\n@end %s\n\n", hook_array[i].doc, deftype); + } + else + printf ("#ifndef %s\n#define %s %s\n#endif\n", + name, name, hook_array[i].init); + } + return 0; +} Index: Makefile.in =================================================================== --- Makefile.in (revision 155367) +++ Makefile.in (working copy) @@ -3714,6 +3714,7 @@ build/genpreds.o : genpreds.c $(RTL_BASE coretypes.h $(GTM_H) errors.h gensupport.h $(OBSTACK_H) build/genrecog.o : genrecog.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ coretypes.h $(GTM_H) errors.h gensupport.h +build/gentarget.o : gentarget.c target.def $(BCONFIG_H) $(SYSTEM_H) # Compile the programs that generate insn-* from the machine description. # They are compiled with $(COMPILER_FOR_BUILD), and associated libraries, @@ -3738,6 +3739,7 @@ build/gengenrtl$(build_exeext) : $(BUILD build/genmodes$(build_exeext) : $(BUILD_ERRORS) build/gengtype$(build_exeext) : build/gengtype-lex.o build/gengtype-parse.o \ $(BUILD_ERRORS) +build/gentarget$(build_exeext) : $(BUILD_ERRORS) # Generated source files for gengtype. gengtype-lex.c : gengtype-lex.l