what you give them. Help stamp out software-hoarding! */
/* This file contains a data structure that describes a GCC target.
- At present, it is incomplete, but in future it should grow to
+ At present it is incomplete, but in future it should grow to
contain most or all target machine and target O/S specific
information.
struct gcc_target targetm = TARGET_INITIALIZER;
Doing things this way allows us to bring together everything that
- defines a target to GCC. By supplying a default that is
- appropriate to most targets, we can easily add new items without
- needing to edit dozens of target configuration files. It should
- also allow us to gradually reduce the amount of conditional
- compilation that is scattered throughout GCC. */
+ defines a GCC target. By supplying a default that is appropriate
+ to most targets, we can easily add new items without needing to
+ edit dozens of target configuration files. It should also allow us
+ to gradually reduce the amount of conditional compilation that is
+ scattered throughout GCC. */
struct gcc_target
{
/* Functions that output assembler for the target. */
struct asm_out
{
+ /* Opening and closing parentheses for asm expression grouping. */
+ const char *open_paren, *close_paren;
+
/* Output the assembler code for entry to a function. */
void (* function_prologue) PARAMS ((FILE *, HOST_WIDE_INT));
+ /* Output the assembler code for end of prologue. */
+ void (* function_end_prologue) PARAMS ((FILE *));
+
+ /* Output the assembler code for start of epilogue. */
+ void (* function_begin_epilogue) PARAMS ((FILE *));
+
/* Output the assembler code for function exit. */
void (* function_epilogue) PARAMS ((FILE *, HOST_WIDE_INT));
+
+ /* Switch to an arbitrary section NAME with attributes as
+ specified by FLAGS. */
+ void (* named_section) PARAMS ((const char *, unsigned int));
+
+ /* Output a constructor for a symbol with a given priority. */
+ void (* constructor) PARAMS ((rtx, int));
+
+ /* Output a destructor for a symbol with a given priority. */
+ void (* destructor) PARAMS ((rtx, int));
} asm_out;
+ /* Functions relating to instruction scheduling. */
+ struct sched
+ {
+ /* Given the current cost, COST, of an insn, INSN, calculate and
+ return a new cost based on its relationship to DEP_INSN through
+ the dependence LINK. The default is to make no adjustment. */
+ int (* adjust_cost) PARAMS ((rtx insn, rtx link, rtx def_insn, int cost));
+
+ /* Adjust the priority of an insn as you see fit. Returns the new
+ priority. */
+ int (* adjust_priority) PARAMS ((rtx, int));
+
+ /* Function which returns the maximum number of insns that can be
+ scheduled in the same machine cycle. This must be constant
+ over an entire compilation. The default is 1. */
+ int (* issue_rate) PARAMS ((void));
+
+ /* Calculate how much this insn affects how many more insns we
+ can emit this cycle. Default is they all cost the same. */
+ int (* variable_issue) PARAMS ((FILE *, int, rtx, int));
+
+ /* Initialize machine-dependent scheduling code. */
+ void (* md_init) PARAMS ((FILE *, int, int));
+
+ /* Finalize machine-dependent scheduling code. */
+ void (* md_finish) PARAMS ((FILE *, int));
+
+ /* Reorder insns in a machine-dependent fashion, in two different
+ places. Default does nothing. */
+ int (* reorder) PARAMS ((FILE *, int, rtx *, int *, int));
+ int (* reorder2) PARAMS ((FILE *, int, rtx *, int *, int));
+
+ /* cycle_display is a pointer to a function which can emit
+ data into the assembly stream about the current cycle.
+ Arguments are CLOCK, the data to emit, and LAST, the last
+ insn in the new chain we're building. Returns a new LAST.
+ The default is to do nothing. */
+ rtx (* cycle_display) PARAMS ((int clock, rtx last));
+ } sched;
+
/* Given two decls, merge their attributes and return the result. */
tree (* merge_decl_attributes) PARAMS ((tree, tree));
/* Given two types, merge their attributes and return the result. */
tree (* merge_type_attributes) PARAMS ((tree, tree));
- /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine
- specific attribute for DECL. The attributes in ATTRIBUTES have
- previously been assigned to DECL. */
- int (* valid_decl_attribute) PARAMS ((tree decl, tree attributes,
- tree identifier, tree args));
-
- /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine
- specific attribute for TYPE. The attributes in ATTRIBUTES have
- previously been assigned to TYPE. */
- int (* valid_type_attribute) PARAMS ((tree type, tree attributes,
- tree identifier, tree args));
+ /* Table of machine attributes and functions to handle them. */
+ const struct attribute_spec *attribute_table;
/* Return zero if the attributes on TYPE1 and TYPE2 are incompatible,
one if they are compatible and two if they are nearly compatible
/* Assign default attributes to the newly defined TYPE. */
void (* set_default_type_attributes) PARAMS ((tree type));
+
+ /* Insert attributes on the newly created DECL. */
+ void (* insert_attributes) PARAMS ((tree decl, tree *attributes));
+
+ /* Return true if FNDECL (which has at least one machine attribute)
+ can be inlined despite its machine attributes, false otherwise. */
+ bool (* function_attribute_inlinable_p) PARAMS ((tree fndecl));
+
+ /* Set up target-specific built-in functions. */
+ void (* init_builtins) PARAMS ((void));
+
+ /* Expand a target-specific builtin. */
+ rtx (* expand_builtin) PARAMS ((tree exp, rtx target, rtx subtarget,
+ enum machine_mode mode, int ignore));
+
+ /* Given a decl, a section name, and whether the decl initializer
+ has relocs, choose attributes for the section. */
+ /* ??? Should be merged with SELECT_SECTION and UNIQUE_SECTION. */
+ unsigned int (* section_type_flags) PARAMS ((tree, const char *, int));
+
+ /* True if arbitrary sections are supported. */
+ bool have_named_sections;
+
+ /* True if "native" constructors and destructors are supported,
+ false if we're using collect2 for the job. */
+ bool have_ctors_dtors;
};
extern struct gcc_target targetm;