$(EXPR_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) except.h reload.h
haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
- $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H)
+ $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(TARGET_H)
sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
$(INSN_ATTR_H) toplev.h $(RECOG_H) except.h cselib.h $(PARAMS_H) $(TM_P_H)
static void output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void a29k_asm_named_section PARAMS ((const char *, unsigned int));
+static int a29k_adjust_cost PARAMS ((rtx, rtx, rtx, int));
#define min(A,B) ((A) < (B) ? (A) : (B))
#define TARGET_ASM_FUNCTION_PROLOGUE output_function_prologue
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE output_function_epilogue
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST a29k_adjust_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* ??? Is it really correct to mark all sections as "bss"? */
fprintf (asm_out_file, "\t.sect %s, bss\n\t.use %s\n", name, name);
}
+
+/* Return a new value for COST based on the relationship between INSN
+ that is dependent on DEP_INSN through the dependence LINK. The
+ default is to make no adjustment to COST.
+
+ On the a29k, ignore the cost of anti- and output-dependencies. */
+static int
+a29k_adjust_cost (insn, link, dep_insn, cost)
+ rtx insn ATTRIBUTE_UNUSED;
+ rtx link;
+ rtx dep_insn ATTRIBUTE_UNUSED;
+ int cost;
+{
+ if (REG_NOTE_KIND (link) != 0)
+ return 0; /* Anti or output dependence. */
+
+ return cost;
+}
most expensive register-register copy. */
#define MEMORY_MOVE_COST(MODE,CLASS,IN) 6
-
-/* A C statement (sans semicolon) to update the integer variable COST
- based on the relationship between INSN that is dependent on
- DEP_INSN through the dependence LINK. The default is to make no
- adjustment to COST. On the a29k, ignore the cost of anti- and
- output-dependencies. */
-#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
- if (REG_NOTE_KIND (LINK) != 0) \
- (COST) = 0; /* Anti or output dependence. */
\f
/* Stack layout; function entry, exit and calling. */
HOST_WIDE_INT));
extern int alpha_expand_block_move PARAMS ((rtx []));
extern int alpha_expand_block_clear PARAMS ((rtx []));
-extern int alpha_adjust_cost PARAMS ((rtx, rtx, rtx, int));
extern rtx alpha_return_addr PARAMS ((int, rtx));
extern rtx alpha_gp_save_rtx PARAMS ((void));
extern void print_operand PARAMS ((FILE *, rtx, int));
PARAMS ((enum rtx_code, rtx, rtx));
static void alpha_output_function_end_prologue
PARAMS ((FILE *));
+static int alpha_adjust_cost
+ PARAMS ((rtx, rtx, rtx, int));
+static int alpha_issue_rate
+ PARAMS ((void));
+static int alpha_variable_issue
+ PARAMS ((FILE *, int, rtx, int));
/* Get the number of args of a function in one of two ways. */
#if TARGET_ABI_OPEN_VMS
#undef TARGET_ASM_FUNCTION_END_PROLOGUE
#define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
+#undef TARGET_SCHED_VARIABLE_ISSUE
+#define TARGET_SCHED_VARIABLE_ISSUE alpha_variable_issue
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Parse target option strings. */
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
-int
+static int
alpha_adjust_cost (insn, link, dep_insn, cost)
rtx insn;
rtx link;
/* Otherwise, return the default cost. */
return cost;
}
+
+/* Function to initialize the issue rate used by the scheduler. */
+static int
+alpha_issue_rate ()
+{
+ return (alpha_cpu == PROCESSOR_EV4 ? 2 : 4);
+}
+
+static int
+alpha_variable_issue (dump, verbose, insn, cim)
+ FILE *dump ATTRIBUTE_UNUSED;
+ int verbose ATTRIBUTE_UNUSED;
+ rtx insn;
+ int cim;
+{
+ if (recog_memoized (insn) < 0 || get_attr_type (insn) == TYPE_MULTI)
+ return 0;
+
+ return cim - 1;
+}
+
\f
/* Functions to save and restore alpha_return_addr_rtx. */
/* Provide the cost of a branch. Exact meaning under development. */
#define BRANCH_COST 5
-
-/* Adjust the cost of dependencies. */
-
-#define ADJUST_COST(INSN,LINK,DEP,COST) \
- (COST) = alpha_adjust_cost (INSN, LINK, DEP, COST)
\f
/* Stack layout; function entry, exit and calling. */
few bits. */
#define SHIFT_COUNT_TRUNCATED 1
-/* The EV4 is dual issue; EV5/EV6 are quad issue. */
-#define ISSUE_RATE (alpha_cpu == PROCESSOR_EV4 ? 2 : 4)
-
-/* Describe the fact that MULTI instructions are multiple instructions
- and so to assume they don't pair with anything. */
-#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \
- if (recog_memoized (INSN) < 0 || get_attr_type (INSN) == TYPE_MULTI) \
- (CAN_ISSUE_MORE) = 0
-
/* Compute the cost of computing a constant rtl expression RTX
whose rtx-code is CODE. The body of this macro is a portion
of a switch statement. If the code is computed here,
extern int legitimate_pic_operand_p PARAMS ((rtx));
extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
extern int arm_rtx_costs PARAMS ((rtx, RTX_CODE, RTX_CODE));
-extern int arm_adjust_cost PARAMS ((rtx, rtx, rtx, int));
extern int const_double_rtx_ok_for_fpu PARAMS ((rtx));
extern int neg_const_double_rtx_ok_for_fpu PARAMS ((rtx));
static void arm_set_default_type_attributes PARAMS ((tree));
static void arm_elf_asm_named_section PARAMS ((const char *,
unsigned int));
+static int arm_adjust_cost PARAMS ((rtx, rtx, rtx, int));
+
#undef Hint
#undef Mmode
#undef Ulong
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN arm_expand_builtin
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Obstack for minipool constant handling. */
}
}
-int
+static int
arm_adjust_cost (insn, link, dep, cost)
rtx insn;
rtx link;
conditional instructions */
#define BRANCH_COST \
(TARGET_ARM ? 4 : (optimize > 1 ? 1 : 0))
-
-/* A C statement to update the variable COST based on the relationship
- between INSN that is dependent on DEP through dependence LINK. */
-#define ADJUST_COST(INSN, LINK, DEP, COST) \
- (COST) = arm_adjust_cost (INSN, LINK, DEP, COST)
\f
/* Position Independent Code. */
/* We decide which register to use based on the compilation options and
#define NO_RECURSIVE_FUNCTION_CSE
/* Define this macro if it is as good or better for a function to call
itself with an explicit address than to call an address kept in a
- register.
-
- `ADJUST_COST (INSN, LINK, DEP_INSN, COST)'
- A C statement (sans semicolon) to update the integer variable COST
- based on the relationship between INSN that is dependent on
- DEP_INSN through the dependence LINK. The default is to make no
- adjustment to COST. This can be used for example to specify to
- the scheduler that an output- or anti-dependence does not incur
- the same cost as a data-dependence.
-
- `ADJUST_PRIORITY (INSN)'
- A C statement (sans semicolon) to update the integer scheduling
- priority `INSN_PRIORITY(INSN)'. Reduce the priority to execute
- the INSN earlier, increase the priority to execute INSN later.
- Do not define this macro if you do not need to adjust the
- scheduling priorities of insns. */
-
+ register. */
#define TEXT_SECTION_ASM_OP "\t.text"
/* A C expression whose value is a string containing the assembler
extern int c4x_address_conflict PARAMS ((rtx, rtx, int, int));
-extern int c4x_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-
extern void c4x_process_after_reload PARAMS ((rtx));
extern void c4x_rptb_insert PARAMS ((rtx insn));
static int c4x_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
static void c4x_insert_attributes PARAMS ((tree, tree *));
static void c4x_asm_named_section PARAMS ((const char *, unsigned int));
+static int c4x_adjust_cost PARAMS ((rtx, rtx, rtx, int));
\f
/* Initialize the GCC target structure. */
#undef TARGET_VALID_TYPE_ATTRIBUTE
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN c4x_expand_builtin
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST c4x_adjust_cost
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Called to register all of our global variables with the garbage
#define SETLDA_USE_COST 2
#define READ_USE_COST 2
-
-int
+static int
c4x_adjust_cost (insn, link, dep_insn, cost)
rtx insn;
rtx link;
#define BRANCH_COST 8
-/* Adjust the cost of dependencies. */
-
-#define ADJUST_COST(INSN,LINK,DEP,COST) \
- (COST) = c4x_adjust_cost (INSN, LINK, DEP, COST)
-
#define WORD_REGISTER_OPERATIONS
/* Dividing the Output into Sections. */
static void expand_movstr_call PARAMS ((rtx *));
static void convex_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void convex_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
+static int convex_adjust_cost PARAMS ((rtx, rtx, rtx, int));
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE convex_output_function_prologue
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE convex_output_function_epilogue
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST convex_adjust_cost
struct gcc_target targetm = TARGET_INITIALIZER;
\f
fprintf (file, "\tds.h 0\n");
}
+/* Adjust the cost of dependences. */
+static int
+convex_adjust_cost (insn, link, dep, cost)
+ rtx insn;
+ rtx link;
+ rtx dep;
+ int cost;
+{
+ /* Antidependencies don't block issue. */
+ if (REG_NOTE_KIND (link) != 0)
+ cost = 0;
+ /* C38 situations where delay depends on context */
+ else if (TARGET_C38
+ && GET_CODE (PATTERN (insn)) == SET
+ && GET_CODE (PATTERN (dep)) == SET)
+ {
+ enum attr_type insn_type = get_attr_type (insn);
+ enum attr_type dep_type = get_attr_type (dep);
+ /* index register must be ready one cycle early */
+ if (insn_type == TYPE_MLDW || insn_type == TYPE_MLDL
+ || (insn_type == TYPE_MST
+ && reg_mentioned_p (SET_DEST (PATTERN (dep)),
+ SET_SRC (PATTERN (insn)))))
+ cost += 1;
+ /* alu forwarding off alu takes two */
+ if (dep_type == TYPE_ALU
+ && insn_type != TYPE_ALU
+ && ! (insn_type == TYPE_MST
+ && SET_DEST (PATTERN (dep)) == SET_SRC (PATTERN (insn))))
+ cost += 1;
+ }
+
+ return cost;
+}
+
+
+
/* Here from OVERRIDE_OPTIONS at startup. Initialize constant tables. */
void
#define BRANCH_COST 0
-/* Adjust the cost of dependences. */
-
-#define ADJUST_COST(INSN,LINK,DEP,COST) \
-{ \
- /* Antidependencies don't block issue. */ \
- if (REG_NOTE_KIND (LINK) != 0) \
- (COST) = 0; \
- /* C38 situations where delay depends on context */ \
- else if (TARGET_C38 \
- && GET_CODE (PATTERN (INSN)) == SET \
- && GET_CODE (PATTERN (DEP)) == SET) \
- { \
- enum attr_type insn_type = get_attr_type (INSN); \
- enum attr_type dep_type = get_attr_type (DEP); \
- /* index register must be ready one cycle early */ \
- if (insn_type == TYPE_MLDW || insn_type == TYPE_MLDL \
- || (insn_type == TYPE_MST \
- && reg_mentioned_p (SET_DEST (PATTERN (DEP)), \
- SET_SRC (PATTERN (INSN))))) \
- (COST) += 1; \
- /* alu forwarding off alu takes two */ \
- if (dep_type == TYPE_ALU \
- && insn_type != TYPE_ALU \
- && ! (insn_type == TYPE_MST \
- && SET_DEST (PATTERN (DEP)) == SET_SRC (PATTERN (INSN)))) \
- (COST) += 1; \
- } \
-}
-
/* Convex uses VAX or IEEE floats.
Follow the host format. */
#define TARGET_FLOAT_FORMAT HOST_FLOAT_FORMAT
extern char *d30v_move_2words PARAMS ((rtx *, rtx));
extern int d30v_emit_cond_move PARAMS ((rtx, rtx, rtx, rtx));
extern void d30v_machine_dependent_reorg PARAMS ((rtx));
-extern int d30v_adjust_cost PARAMS ((rtx, rtx, rtx, int));
extern rtx d30v_return_addr PARAMS ((void));
#endif
extern void d30v_init_expanders PARAMS ((void));
static void d30v_free_machine_status PARAMS ((struct function *));
static void d30v_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void d30v_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
+static int d30v_adjust_cost PARAMS ((rtx, rtx, rtx, int));
+static int d30v_issue_rate PARAMS ((void));
/* Define the information needed to generate branch and scc insns. This is
stored from the compare operation. */
#define TARGET_ASM_FUNCTION_PROLOGUE d30v_output_function_prologue
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE d30v_output_function_epilogue
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST d30v_adjust_cost
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE d30v_issue_rate
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* For the d30v, try to insure that the source operands for a load/store are
set 2 cycles before the memory reference. */
-int
+static int
d30v_adjust_cost (insn, link, dep_insn, cost)
rtx insn;
rtx link ATTRIBUTE_UNUSED;
|| (GET_CODE (mem = SET_DEST (set_insn)) == MEM
&& reg_mentioned_p (reg, XEXP (mem, 0))))
{
- return cost + ((HAIFA_P) ? 2 : 4);
+ return cost + 2;
}
}
return cost;
}
+/* Function which returns the number of insns that can be
+ scheduled in the same machine cycle. This must be constant
+ over an entire compilation. The default is 1. */
+static int
+d30v_issue_rate ()
+{
+ return 2;
+}
+
\f
/* Routine to allocate, mark and free a per-function,
machine specific structure. */
with an explicit address than to call an address kept in a register. */
/* #define NO_RECURSIVE_FUNCTION_CSE */
-/* A C statement (sans semicolon) to update the integer variable COST based on
- the relationship between INSN that is dependent on DEP_INSN through the
- dependence LINK. The default is to make no adjustment to COST. This can be
- used for example to specify to the scheduler that an output- or
- anti-dependence does not incur the same cost as a data-dependence. */
-
-#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
- (COST) = d30v_adjust_cost (INSN, LINK, DEP_INSN, COST)
-
-/* A C statement (sans semicolon) to update the integer scheduling
- priority `INSN_PRIORITY(INSN)'. Reduce the priority to execute
- the INSN earlier, increase the priority to execute INSN later.
- Do not define this macro if you do not need to adjust the
- scheduling priorities of insns. */
-/* #define ADJUST_PRIORITY (INSN) */
-
-/* Macro to determine whether the Haifa scheduler is used. */
-#ifdef HAIFA
-#define HAIFA_P 1
-#else
-#define HAIFA_P 0
-#endif
-
\f
/* Dividing the output into sections. */
extern int d30v_cond_exec;
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 */
extern int ix86_attr_length_immediate_default PARAMS ((rtx, int));
extern int ix86_attr_length_address_default PARAMS ((rtx));
-extern int ix86_issue_rate PARAMS ((void));
-extern int ix86_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-extern void ix86_sched_init PARAMS ((FILE *, int));
-extern int ix86_sched_reorder PARAMS ((FILE *, int, rtx *, int, int));
-extern int ix86_variable_issue PARAMS ((FILE *, int, rtx, int));
extern enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
extern int x86_64_sign_extended_value PARAMS ((rtx));
static void ix86_adjust_counter PARAMS ((rtx, HOST_WIDE_INT));
static rtx ix86_expand_aligntest PARAMS ((rtx, int));
static void ix86_expand_strlensi_unroll_1 PARAMS ((rtx, rtx));
+static int ix86_issue_rate PARAMS ((void));
+static int ix86_adjust_cost PARAMS ((rtx, rtx, rtx, int));
+static void ix86_sched_init PARAMS ((FILE *, int, int));
+static int ix86_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
+static int ix86_variable_issue PARAMS ((FILE *, int, rtx, int));
struct ix86_address
{
#undef TARGET_ASM_CLOSE_PAREN
#define TARGET_ASM_CLOSE_PAREN ""
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
+#undef TARGET_SCHED_VARIABLE_ISSUE
+#define TARGET_SCHED_VARIABLE_ISSUE ix86_variable_issue
+#undef TARGET_SCHED_INIT
+#define TARGET_SCHED_INIT ix86_sched_init
+#undef TARGET_SCHED_REORDER
+#define TARGET_SCHED_REORDER ix86_sched_reorder
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Sometimes certain combinations of command options do not make
\f
/* Return the maximum number of instructions a cpu can issue. */
-int
+static int
ix86_issue_rate ()
{
switch (ix86_cpu)
return modified_in_p (addr, dep_insn);
}
-int
+static int
ix86_adjust_cost (insn, link, dep_insn, cost)
rtx insn, link, dep_insn;
int cost;
/* We're beginning a new block. Initialize data structures as necessary. */
-void
-ix86_sched_init (dump, sched_verbose)
+static void
+ix86_sched_init (dump, sched_verbose, veclen)
FILE *dump ATTRIBUTE_UNUSED;
int sched_verbose ATTRIBUTE_UNUSED;
+ int veclen ATTRIBUTE_UNUSED;
{
memset (&ix86_sched_data, 0, sizeof (ix86_sched_data));
}
/* We are about to being issuing insns for this clock cycle.
Override the default sort algorithm to better slot instructions. */
-int
-ix86_sched_reorder (dump, sched_verbose, ready, n_ready, clock_var)
+static int
+ix86_sched_reorder (dump, sched_verbose, ready, n_readyp, clock_var)
FILE *dump ATTRIBUTE_UNUSED;
int sched_verbose ATTRIBUTE_UNUSED;
rtx *ready;
- int n_ready;
+ int *n_readyp;
int clock_var ATTRIBUTE_UNUSED;
{
+ int n_ready = *n_readyp;
rtx *e_ready = ready + n_ready - 1;
if (n_ready < 2)
/* We are about to issue INSN. Return the number of insns left on the
ready queue that can be issued this cycle. */
-int
+static int
ix86_variable_issue (dump, sched_verbose, insn, can_issue_more)
FILE *dump;
int sched_verbose;
register. */
#define NO_RECURSIVE_FUNCTION_CSE
-
-/* A C statement (sans semicolon) to update the integer variable COST
- based on the relationship between INSN that is dependent on
- DEP_INSN through the dependence LINK. The default is to make no
- adjustment to COST. This can be used for example to specify to
- the scheduler that an output- or anti-dependence does not incur
- the same cost as a data-dependence. */
-
-#define ADJUST_COST(insn,link,dep_insn,cost) \
- (cost) = ix86_adjust_cost(insn, link, dep_insn, cost)
-
-#define ISSUE_RATE \
- ix86_issue_rate ()
-
-#define MD_SCHED_INIT(DUMP, SCHED_VERBOSE, MAX_READY) \
- ix86_sched_init (DUMP, SCHED_VERBOSE)
-
-#define MD_SCHED_REORDER(DUMP, SCHED_VERBOSE, READY, N_READY, CLOCK, CIM) \
- (CIM) = ix86_sched_reorder (DUMP, SCHED_VERBOSE, READY, N_READY, CLOCK)
-
-#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \
- ((CAN_ISSUE_MORE) = \
- ix86_variable_issue (DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE))
\f
/* Add any extra modes needed to represent the condition code.
extern void ia64_reorg PARAMS((rtx));
extern void process_for_unwind_directive PARAMS ((FILE *, rtx));
extern const char *get_bundle_name PARAMS ((int));
-extern int ia64_issue_rate PARAMS ((void));
-extern int ia64_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-extern void ia64_sched_init PARAMS ((FILE *, int, int));
-extern void ia64_sched_finish PARAMS ((FILE *, int));
-extern int ia64_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int, int));
-extern int ia64_sched_reorder2 PARAMS ((FILE *, int, rtx *, int *, int));
-extern int ia64_variable_issue PARAMS ((FILE *, int, rtx, int));
#endif /* RTX_CODE */
#ifdef TREE_CODE
static void ia64_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void ia64_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void ia64_output_function_end_prologue PARAMS ((FILE *));
+
+static int ia64_issue_rate PARAMS ((void));
+static int ia64_adjust_cost PARAMS ((rtx, rtx, rtx, int));
+static void ia64_sched_init PARAMS ((FILE *, int, int));
+static void ia64_sched_finish PARAMS ((FILE *, int));
+static int ia64_internal_sched_reorder PARAMS ((FILE *, int, rtx *,
+ int *, int, int));
+static int ia64_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
+static int ia64_sched_reorder2 PARAMS ((FILE *, int, rtx *, int *, int));
+static int ia64_variable_issue PARAMS ((FILE *, int, rtx, int));
+static rtx ia64_cycle_display PARAMS ((int, rtx));
+
\f
/* Initialize the GCC target structure. */
#undef TARGET_VALID_TYPE_ATTRIBUTE
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE ia64_output_function_epilogue
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST ia64_adjust_cost
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE ia64_issue_rate
+#undef TARGET_SCHED_VARIABLE_ISSUE
+#define TARGET_SCHED_VARIABLE_ISSUE ia64_variable_issue
+#undef TARGET_SCHED_INIT
+#define TARGET_SCHED_INIT ia64_sched_init
+#undef TARGET_SCHED_FINISH
+#define TARGET_SCHED_FINISH ia64_sched_finish
+#undef TARGET_SCHED_REORDER
+#define TARGET_SCHED_REORDER ia64_sched_reorder
+#undef TARGET_SCHED_REORDER2
+#define TARGET_SCHED_REORDER2 ia64_sched_reorder2
+#undef TARGET_SCHED_CYCLE_DISPLAY
+#define TARGET_SCHED_CYCLE_DISPLAY ia64_cycle_display
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
/* Return the maximum number of instructions a cpu can issue. */
-int
+static int
ia64_issue_rate ()
{
return 6;
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
-int
+static int
ia64_adjust_cost (insn, link, dep_insn, cost)
rtx insn, link, dep_insn;
int cost;
/* We're beginning a new block. Initialize data structures as necessary. */
-void
+static void
ia64_sched_init (dump, sched_verbose, max_ready)
FILE *dump ATTRIBUTE_UNUSED;
int sched_verbose ATTRIBUTE_UNUSED;
/* We are about to being issuing insns for this clock cycle.
Override the default sort algorithm to better slot instructions. */
-int
-ia64_sched_reorder (dump, sched_verbose, ready, pn_ready,
+static int
+ia64_internal_sched_reorder (dump, sched_verbose, ready, pn_ready,
reorder_type, clock_var)
FILE *dump ATTRIBUTE_UNUSED;
int sched_verbose ATTRIBUTE_UNUSED;
ready, e_ready, reorder_type == 1);
}
+static int
+ia64_sched_reorder (dump, sched_verbose, ready, pn_ready, clock_var)
+ FILE *dump;
+ int sched_verbose;
+ rtx *ready;
+ int *pn_ready;
+ int clock_var;
+{
+ return ia64_internal_sched_reorder (dump, sched_verbose, ready,
+ pn_ready, 0, clock_var);
+}
+
/* Like ia64_sched_reorder, but called after issuing each insn.
Override the default sort algorithm to better slot instructions. */
-int
+static int
ia64_sched_reorder2 (dump, sched_verbose, ready, pn_ready, clock_var)
FILE *dump ATTRIBUTE_UNUSED;
int sched_verbose ATTRIBUTE_UNUSED;
if (*pn_ready > 0)
{
- int more = ia64_sched_reorder (dump, sched_verbose, ready, pn_ready, 1,
- clock_var);
+ int more = ia64_internal_sched_reorder (dump, sched_verbose,
+ ready, pn_ready, 1,
+ clock_var);
if (more)
return more;
/* Did we schedule a stop? If so, finish this cycle. */
/* We are about to issue INSN. Return the number of insns left on the
ready queue that can be issued this cycle. */
-int
+static int
ia64_variable_issue (dump, sched_verbose, insn, can_issue_more)
FILE *dump;
int sched_verbose;
/* Free data allocated by ia64_sched_init. */
-void
+static void
ia64_sched_finish (dump, sched_verbose)
FILE *dump;
int sched_verbose;
free (sched_types);
free (sched_ready);
}
+
+static rtx
+ia64_cycle_display (clock, last)
+ int clock;
+ rtx last;
+{
+ return emit_insn_after (gen_cycle_display (GEN_INT (clock)), last);
+}
\f
/* Emit pseudo-ops for the assembler to describe predicate relations.
At present this assumes that we only consider predicate pairs to
/* ??? Investigate. */
#define MAX_CONDITIONAL_EXECUTE 12
-/* A C statement (sans semicolon) to update the integer scheduling
- priority `INSN_PRIORITY(INSN)'. */
-
-/* ??? Investigate. */
-/* #define ADJUST_PRIORITY (INSN) */
-
-/* A C statement (sans semicolon) to update the integer variable COST
- based on the relationship between INSN that is dependent on
- DEP_INSN through the dependence LINK. The default is to make no
- adjustment to COST. This can be used for example to specify to
- the scheduler that an output- or anti-dependence does not incur
- the same cost as a data-dependence. */
-
-#define ADJUST_COST(insn,link,dep_insn,cost) \
- (cost) = ia64_adjust_cost(insn, link, dep_insn, cost)
-
-#define ISSUE_RATE ia64_issue_rate ()
-
-#define MD_SCHED_INIT(DUMP, SCHED_VERBOSE, MAX_READY) \
- ia64_sched_init (DUMP, SCHED_VERBOSE, MAX_READY)
-
-#define MD_SCHED_REORDER(DUMP, SCHED_VERBOSE, READY, N_READY, CLOCK, CIM) \
- (CIM) = ia64_sched_reorder (DUMP, SCHED_VERBOSE, READY, &N_READY, 0, CLOCK)
-
-#define MD_SCHED_REORDER2(DUMP, SCHED_VERBOSE, READY, N_READY, CLOCK, CIM) \
- (CIM) = ia64_sched_reorder2 (DUMP, SCHED_VERBOSE, READY, &N_READY, CLOCK)
-
-#define MD_SCHED_FINISH(DUMP, SCHED_VERBOSE) \
- ia64_sched_finish (DUMP, SCHED_VERBOSE)
-
-#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \
- ((CAN_ISSUE_MORE) \
- = ia64_variable_issue (DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE))
-
extern int ia64_final_schedule;
#define IA64_UNWIND_INFO 1
extern void m32r_expand_prologue PARAMS ((void));
extern void m32r_finalize_pic PARAMS ((void));
extern void m32r_asm_file_start PARAMS ((FILE *));
-extern void m32r_sched_init PARAMS ((FILE *, int));
extern int direct_return PARAMS ((void));
#ifdef TREE_CODE
extern void m32r_select_section PARAMS ((tree, int));
extern void m32r_print_operand PARAMS ((FILE *, rtx, int));
extern void m32r_print_operand_address PARAMS ((FILE *, rtx));
extern int m32r_address_cost PARAMS ((rtx));
-extern int m32r_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-extern int m32r_adjust_priority PARAMS ((rtx, int));
-extern void m32r_sched_reorder PARAMS ((FILE *, int, rtx *, int));
-extern int m32r_sched_variable_issue PARAMS ((FILE *, int, rtx, int));
extern int m32r_not_same_reg PARAMS ((rtx, rtx));
#ifdef HAVE_MACHINE_MODES
enum m32r_sdata m32r_sdata;
/* Scheduler support */
-int m32r_sched_odd_word_p;
+static int m32r_sched_odd_word_p;
/* Forward declaration. */
static void init_reg_tables PARAMS ((void));
tree, tree));
static void m32r_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void m32r_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
+
+static int m32r_adjust_cost PARAMS ((rtx, rtx, rtx, int));
+static int m32r_adjust_priority PARAMS ((rtx, int));
+static void m32r_sched_init PARAMS ((FILE *, int));
+static int m32r_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
+static int m32r_variable_issue PARAMS ((FILE *, int, rtx, int));
+static int m32r_issue_rate PARAMS ((void));
+
\f
/* Initialize the GCC target structure. */
#undef TARGET_VALID_DECL_ATTRIBUTE
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE m32r_output_function_epilogue
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST m32r_adjust_cost
+#undef TARGET_SCHED_ADJUST_PRIORITY
+#define TARGET_SCHED_ADJUST_PRIORITY m32r_adjust_priority
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE m32r_issue_rate
+#undef TARGET_SCHED_VARIABLE_ISSUE
+#define TARGET_SCHED_VARIABLE_ISSUE m32r_variable_issue
+#undef TARGET_SCHED_INIT
+#define TARGET_SCHED_INIT m32r_sched_init
+#undef TARGET_SCHED_REORDER
+#define TARGET_SCHED_REORDER m32r_sched_reorder
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Called by OVERRIDE_OPTIONS to initialize various things. */
return addr_rtx;
}
\f
-int
+static int
m32r_adjust_cost (insn, link, dep_insn, cost)
rtx insn ATTRIBUTE_UNUSED;
rtx link ATTRIBUTE_UNUSED;
/* Increase the priority of long instructions so that the
short instructions are scheduled ahead of the long ones. */
-int
+static int
m32r_adjust_priority (insn, priority)
rtx insn;
int priority;
\f
/* Initialize for scheduling a group of instructions. */
-void
+static void
m32r_sched_init (stream, verbose)
FILE * stream ATTRIBUTE_UNUSED;
int verbose ATTRIBUTE_UNUSED;
\f
/* Reorder the schedulers priority list if needed */
-void
-m32r_sched_reorder (stream, verbose, ready, n_ready)
+static int
+m32r_sched_reorder (stream, verbose, ready, n_readyp, clock)
FILE * stream;
int verbose;
rtx * ready;
- int n_ready;
+ int *n_readyp;
+ int clock ATTRIBUTE_UNUSED;
{
+ int n_ready = *n_readyp;
+
if (TARGET_DEBUG)
- return;
+ return m32r_issue_rate ();
if (verbose <= 7)
stream = (FILE *)0;
memcpy (ready, new_head, sizeof (rtx) * n_ready);
if (stream)
{
-#ifdef HAIFA
- fprintf (stream, ";;\t\t::: New ready list: ");
- debug_ready_list (ready, n_ready);
-#else
int i;
+ fprintf (stream, ";;\t\t::: New ready list: ");
for (i = 0; i < n_ready; i++)
{
rtx insn = ready[i];
}
fprintf (stream, "\n");
-#endif
}
}
+ return m32r_issue_rate ();
+}
+
+/* Indicate how many instructions can be issued at the same time.
+ This is sort of a lie. The m32r can issue only 1 long insn at
+ once, but it can issue 2 short insns. The default therefore is
+ set at 2, but this can be overridden by the command line option
+ -missue-rate=1 */
+static int
+m32r_issue_rate ()
+{
+ return ((TARGET_LOW_ISSUE_RATE) ? 1 : 2);
}
-\f
/* If we have a machine that can issue a variable # of instructions
per cycle, indicate how many more instructions can be issued
after the current one. */
-int
-m32r_sched_variable_issue (stream, verbose, insn, how_many)
+static int
+m32r_variable_issue (stream, verbose, insn, how_many)
FILE * stream;
int verbose;
rtx insn;
#define TARGET_ALIGN_LOOPS (target_flags & TARGET_ALIGN_LOOPS_MASK)
/* Change issue rate. */
-#define TARGET_ISSUE_RATE_MASK (1 << 3)
-#define TARGET_ISSUE_RATE (target_flags & TARGET_ISSUE_RATE_MASK)
+#define TARGET_LOW_ISSUE_RATE_MASK (1 << 3)
+#define TARGET_LOW_ISSUE_RATE (target_flags & TARGET_LOW_ISSUE_RATE_MASK)
/* Change branch cost */
#define TARGET_BRANCH_COST_MASK (1 << 4)
{ "align-loops", TARGET_ALIGN_LOOPS_MASK, \
N_("Align all loops to 32 byte boundary") }, \
{ "no-align-loops", -TARGET_ALIGN_LOOPS_MASK, "" }, \
- { "issue-rate=1", TARGET_ISSUE_RATE_MASK, \
+ { "issue-rate=1", TARGET_LOW_ISSUE_RATE_MASK, \
N_("Only issue one instruction per cycle") }, \
- { "issue-rate=2", -TARGET_ISSUE_RATE_MASK, "" }, \
+ { "issue-rate=2", -TARGET_LOW_ISSUE_RATE_MASK, "" }, \
{ "branch-cost=1", TARGET_BRANCH_COST_MASK, \
N_("Prefer branches over conditional execution") }, \
{ "branch-cost=2", -TARGET_BRANCH_COST_MASK, "" }, \
register. */
#define NO_RECURSIVE_FUNCTION_CSE
-/* A C statement (sans semicolon) to update the integer variable COST based on
- the relationship between INSN that is dependent on DEP_INSN through the
- dependence LINK. The default is to make no adjustment to COST. This can be
- used for example to specify to the scheduler that an output- or
- anti-dependence does not incur the same cost as a data-dependence. */
-
-#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
- (COST) = m32r_adjust_cost (INSN, LINK, DEP_INSN, COST)
-
-/* A C statement (sans semicolon) to update the integer scheduling
- priority `INSN_PRIORITY(INSN)'. Reduce the priority to execute
- the INSN earlier, increase the priority to execute INSN later.
- Do not define this macro if you do not need to adjust the
- scheduling priorities of insns. */
-#define ADJUST_PRIORITY(INSN) \
- INSN_PRIORITY (INSN) = m32r_adjust_priority (INSN, INSN_PRIORITY (INSN))
-
-/* Macro to determine whether the Haifa scheduler is used. */
-#ifdef HAIFA
-#define HAIFA_P 1
-#else
-#define HAIFA_P 0
-#endif
-
-/* Indicate how many instructions can be issued at the same time.
- This is sort of a lie. The m32r can issue only 1 long insn at
- once, but it can issue 2 short insns. The default therefore is
- set at 2, but this can be overridden by the command line option
- -missue-rate=1 */
-#define ISSUE_RATE ((TARGET_ISSUE_RATE) ? 1 : 2)
-
-/* If we have a machine that can issue a variable # of instructions
- per cycle, indicate how many more instructions can be issued
- after the current one. */
-#define MD_SCHED_VARIABLE_ISSUE(STREAM, VERBOSE, INSN, HOW_MANY) \
-(HOW_MANY) = m32r_sched_variable_issue (STREAM, VERBOSE, INSN, HOW_MANY)
-
-/* Whether we are on an odd word boundary while scheduling. */
-extern int m32r_sched_odd_word_p;
-
-/* Hook to run before scheduling a block of insns. */
-#define MD_SCHED_INIT(STREAM, VERBOSE, MAX_READY) \
- m32r_sched_init (STREAM, VERBOSE)
-
-/* Hook to reorder the list of ready instructions. */
-#define MD_SCHED_REORDER(STREAM, VERBOSE, READY, N_READY, CLOCK, CIM) \
- do \
- { \
- m32r_sched_reorder (STREAM, VERBOSE, READY, N_READY); \
- CIM = issue_rate; \
- } \
- while (0)
-
/* When the `length' insn attribute is used, this macro specifies the
value to be assigned to the address of the first insn in a
function. If not specified, 0 is used. */
static void m88k_svr3_asm_out_constructor PARAMS ((rtx, int));
static void m88k_svr3_asm_out_destructor PARAMS ((rtx, int));
#endif
+
+static int m88k_adjust_cost PARAMS ((rtx, rtx, rtx, int));
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_FUNCTION_PROLOGUE
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE m88k_output_function_epilogue
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST m88k_adjust_cost
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Determine what instructions are needed to manufacture the integer VALUE
assemble_integer (constm1_rtx, UNITS_PER_WORD, BITS_PER_WORD, 1);
}
#endif
+
+/* Adjust the cost of INSN based on the relationship between INSN that
+ is dependent on DEP_INSN through the dependence LINK. The default
+ is to make no adjustment to COST.
+
+ On the m88k, ignore the cost of anti- and output-dependencies. On
+ the m88100, a store can issue two cycles before the value (not the
+ address) has finished computing. */
+
+static int
+m88k_adjust_cost (insn, link, dep, cost)
+ rtx insn;
+ rtx link;
+ rtx dep;
+ int cost;
+{
+ if (REG_NOTE_KIND (link) != 0)
+ return 0; /* Anti or output dependence. */
+
+ if (! TARGET_88100
+ && recog_memoized (insn) >= 0
+ && get_attr_type (insn) == TYPE_STORE
+ && SET_SRC (PATTERN (insn)) == SET_DEST (PATTERN (dep)))
+ return cost - 4; /* 88110 store reservation station. */
+
+ return cost;
+}
/* Provide the cost of a branch. Exact meaning under development. */
#define BRANCH_COST (TARGET_88100 ? 1 : 2)
-/* A C statement (sans semicolon) to update the integer variable COST
- based on the relationship between INSN that is dependent on
- DEP_INSN through the dependence LINK. The default is to make no
- adjustment to COST. On the m88k, ignore the cost of anti- and
- output-dependencies. On the m88100, a store can issue two cycles
- before the value (not the address) has finished computing. */
-#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
- do { \
- if (REG_NOTE_KIND (LINK) != 0) \
- (COST) = 0; /* Anti or output dependence. */ \
- else if (! TARGET_88100 \
- && recog_memoized (INSN) >= 0 \
- && get_attr_type (INSN) == TYPE_STORE \
- && SET_SRC (PATTERN (INSN)) == SET_DEST (PATTERN (DEP_INSN))) \
- (COST) -= 4; /* 88110 store reservation station. */ \
- } while (0)
-
/* Do not break .stabs pseudos into continuations. */
#define DBX_CONTIN_LENGTH 0
\f
static hashval_t iris_section_align_entry_hash PARAMS ((const PTR));
static int iris6_section_align_1 PARAMS ((void **, void *));
#endif
+static int mips_adjust_cost PARAMS ((rtx, rtx, rtx, int));
/* Global variables for machine-dependent things. */
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE mips_output_function_epilogue
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST mips_adjust_cost
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Return truth value of whether OP can be used as an operands
return cpu;
}
+/* Adjust the cost of INSN based on the relationship between INSN that
+ is dependent on DEP_INSN through the dependence LINK. The default
+ is to make no adjustment to COST.
+
+ On the MIPS, ignore the cost of anti- and output-dependencies. */
+static int
+mips_adjust_cost (insn, link, dep, cost)
+ rtx insn ATTRIBUTE_UNUSED;
+ rtx link;
+ rtx dep ATTRIBUTE_UNUSED;
+ int cost;
+{
+ if (REG_NOTE_KIND (link) != 0)
+ return 0; /* Anti or output dependence. */
+ return cost;
+}
+
/* Cover function for UNIQUE_SECTION. */
void
DECL_SECTION_NAME (decl) = build_string (len, string);
}
+
\f
#ifdef TARGET_IRIX6
/* Output assembly to switch to section NAME with attribute FLAGS. */
&& (TUNE_MIPS4000 || TUNE_MIPS6000)) \
? 2 : 1)
-/* A C statement (sans semicolon) to update the integer variable COST
- based on the relationship between INSN that is dependent on
- DEP_INSN through the dependence LINK. The default is to make no
- adjustment to COST. On the MIPS, ignore the cost of anti- and
- output-dependencies. */
-
-#define ADJUST_COST(INSN,LINK,DEP_INSN,COST) \
- if (REG_NOTE_KIND (LINK) != 0) \
- (COST) = 0; /* Anti or output dependence. */
-
/* If defined, modifies the length assigned to instruction INSN as a
function of the context in which it is used. LENGTH is an lvalue
that contains the initially computed length of the insn and should
extern int symbolic_expression_p PARAMS ((rtx));
extern int hppa_address_cost PARAMS ((rtx));
extern int symbolic_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int pa_adjust_cost PARAMS ((rtx, rtx, rtx, int));
extern int pa_adjust_insn_length PARAMS ((rtx, int));
extern int int11_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_cint_move_operand PARAMS ((rtx, enum machine_mode));
static rtx load_reg PARAMS ((int, int, int));
static rtx set_reg_plus_d PARAMS ((int, int, int));
static void pa_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
+static int pa_adjust_cost PARAMS ((rtx, rtx, rtx, int));
+static int pa_adjust_priority PARAMS ((rtx, int));
+static int pa_issue_rate PARAMS ((void));
/* Save the operands last given to a compare for use when we
generate a scc or bcc insn. */
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE pa_output_function_epilogue
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST pa_adjust_cost
+#undef TARGET_SCHED_ADJUST_PRIORITY
+#define TARGET_SCHED_ADJUST_PRIORITY pa_adjust_priority
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE pa_issue_rate
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
void
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
-int
+static int
pa_adjust_cost (insn, link, dep_insn, cost)
rtx insn;
rtx link;
abort ();
}
+/* Adjust scheduling priorities. We use this to try and keep addil
+ and the next use of %r1 close together. */
+static int
+pa_adjust_priority (insn, priority)
+ rtx insn;
+ int priority;
+{
+ rtx set = single_set (insn);
+ rtx src, dest;
+ if (set)
+ {
+ src = SET_SRC (set);
+ dest = SET_DEST (set);
+ if (GET_CODE (src) == LO_SUM
+ && symbolic_operand (XEXP (src, 1), VOIDmode)
+ && ! read_only_operand (XEXP (src, 1), VOIDmode))
+ priority >>= 3;
+
+ else if (GET_CODE (src) == MEM
+ && GET_CODE (XEXP (src, 0)) == LO_SUM
+ && symbolic_operand (XEXP (XEXP (src, 0), 1), VOIDmode)
+ && ! read_only_operand (XEXP (XEXP (src, 0), 1), VOIDmode))
+ priority >>= 1;
+
+ else if (GET_CODE (dest) == MEM
+ && GET_CODE (XEXP (dest, 0)) == LO_SUM
+ && symbolic_operand (XEXP (XEXP (dest, 0), 1), VOIDmode)
+ && ! read_only_operand (XEXP (XEXP (dest, 0), 1), VOIDmode))
+ priority >>= 3;
+ }
+ return priority;
+}
+
+/* The 700 can only issue a single insn at a time.
+ The 7XXX processors can issue two insns at a time.
+ The 8000 can issue 4 insns at a time. */
+static int
+pa_issue_rate ()
+{
+ switch (pa_cpu)
+ {
+ case PROCESSOR_700: return 1;
+ case PROCESSOR_7100: return 2;
+ case PROCESSOR_7100LC: return 2;
+ case PROCESSOR_7200: return 2;
+ case PROCESSOR_8000: return 4;
+
+ default:
+ abort ();
+ }
+}
+
+
+
/* Return any length adjustment needed by INSN which already has its length
computed as LENGTH. Return zero if no adjustment is necessary.
#define pa_cpu_attr ((enum attr_cpu)pa_cpu)
-/* The 700 can only issue a single insn at a time.
- The 7XXX processors can issue two insns at a time.
- The 8000 can issue 4 insns at a time. */
-#define ISSUE_RATE \
- (pa_cpu == PROCESSOR_700 ? 1 \
- : pa_cpu == PROCESSOR_7100 ? 2 \
- : pa_cpu == PROCESSOR_7100LC ? 2 \
- : pa_cpu == PROCESSOR_7200 ? 2 \
- : pa_cpu == PROCESSOR_8000 ? 4 \
- : 2)
-
/* Which architecture to generate code for. */
enum architecture_type
/* Adjust the cost of branches. */
#define BRANCH_COST (pa_cpu == PROCESSOR_8000 ? 2 : 1)
-/* Adjust the cost of dependencies. */
-
-#define ADJUST_COST(INSN,LINK,DEP,COST) \
- (COST) = pa_adjust_cost (INSN, LINK, DEP, COST)
-
-/* Adjust scheduling priorities. We use this to try and keep addil
- and the next use of %r1 close together. */
-#define ADJUST_PRIORITY(PREV) \
- { \
- rtx set = single_set (PREV); \
- rtx src, dest; \
- if (set) \
- { \
- src = SET_SRC (set); \
- dest = SET_DEST (set); \
- if (GET_CODE (src) == LO_SUM \
- && symbolic_operand (XEXP (src, 1), VOIDmode) \
- && ! read_only_operand (XEXP (src, 1), VOIDmode)) \
- INSN_PRIORITY (PREV) >>= 3; \
- else if (GET_CODE (src) == MEM \
- && GET_CODE (XEXP (src, 0)) == LO_SUM \
- && symbolic_operand (XEXP (XEXP (src, 0), 1), VOIDmode)\
- && ! read_only_operand (XEXP (XEXP (src, 0), 1), VOIDmode))\
- INSN_PRIORITY (PREV) >>= 1; \
- else if (GET_CODE (dest) == MEM \
- && GET_CODE (XEXP (dest, 0)) == LO_SUM \
- && symbolic_operand (XEXP (XEXP (dest, 0), 1), VOIDmode)\
- && ! read_only_operand (XEXP (XEXP (dest, 0), 1), VOIDmode))\
- INSN_PRIORITY (PREV) >>= 3; \
- } \
- }
-
/* Handling the special cases is going to get too complicated for a macro,
just call `pa_adjust_insn_length' to do the real work. */
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
extern int rs6000_emit_cmove PARAMS ((rtx, rtx, rtx, rtx));
extern void rs6000_emit_minmax PARAMS ((rtx, enum rtx_code, rtx, rtx));
extern void output_toc PARAMS ((FILE *, rtx, int, enum machine_mode));
-extern int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-extern int rs6000_adjust_priority PARAMS ((rtx, int));
extern void rs6000_initialize_trampoline PARAMS ((rtx, rtx, rtx));
extern struct rtx_def *rs6000_longcall_ref PARAMS ((rtx));
extern void rs6000_fatal_bad_address PARAMS ((rtx));
extern struct rtx_def *rs6000_float_const PARAMS ((const char *,
enum machine_mode));
extern int direct_return PARAMS ((void));
-extern int get_issue_rate PARAMS ((void));
extern union tree_node *rs6000_build_va_list PARAMS ((void));
extern int first_reg_to_save PARAMS ((void));
extern int first_fp_reg_to_save PARAMS ((void));
#ifdef OBJECT_FORMAT_COFF
static void xcoff_asm_named_section PARAMS ((const char *, unsigned int));
#endif
+static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
+static int rs6000_adjust_priority PARAMS ((rtx, int));
+static int rs6000_issue_rate PARAMS ((void));
+
\f
/* Default register names. */
char rs6000_reg_names[][8] =
#define TARGET_SECTION_TYPE_FLAGS rs6000_elf_section_type_flags
#endif
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
+#undef TARGET_SCHED_ADJUST_PRIORITY
+#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Override command line options. Mostly we process the processor
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
-int
+static int
rs6000_adjust_cost (insn, link, dep_insn, cost)
rtx insn;
rtx link;
increase the priority to execute INSN later. Do not define this macro if
you do not need to adjust the scheduling priorities of insns. */
-int
+static int
rs6000_adjust_priority (insn, priority)
rtx insn ATTRIBUTE_UNUSED;
int priority;
}
/* Return how many instructions the machine can issue per cycle */
-int get_issue_rate()
+static int
+rs6000_issue_rate ()
{
switch (rs6000_cpu_attr) {
case CPU_RIOS1: /* ? */
#define BRANCH_COST 3
-/* A C statement (sans semicolon) to update the integer variable COST
- based on the relationship between INSN that is dependent on
- DEP_INSN through the dependence LINK. The default is to make no
- adjustment to COST. On the RS/6000, ignore the cost of anti- and
- output-dependencies. In fact, output dependencies on the CR do have
- a cost, but it is probably not worthwhile to track it. */
-
-#define ADJUST_COST(INSN, LINK, DEP_INSN, COST) \
- (COST) = rs6000_adjust_cost (INSN,LINK,DEP_INSN,COST)
-
-/* A C statement (sans semicolon) to update the integer scheduling priority
- INSN_PRIORITY (INSN). Reduce the priority to execute the INSN earlier,
- increase the priority to execute INSN later. Do not define this macro if
- you do not need to adjust the scheduling priorities of insns. */
-
-#define ADJUST_PRIORITY(INSN) \
- INSN_PRIORITY (INSN) = rs6000_adjust_priority (INSN, INSN_PRIORITY (INSN))
-
/* Define this macro to change register usage conditional on target flags.
Set MQ register fixed (already call_used) if not POWER architecture
(RIOS1, RIOS2, RSC, and PPC601) so that it will not be allocated.
/* #define MACHINE_no_sched_speculative */
/* #define MACHINE_no_sched_speculative_load */
-/* indicate that issue rate is defined for this machine
- (no need to use the default) */
-#define ISSUE_RATE get_issue_rate ()
-
/* General flags. */
extern int flag_pic;
extern int optimize;
extern void s390_output_symbolic_const PARAMS ((FILE *, rtx));
extern void print_operand_address PARAMS ((FILE *, rtx));
extern void print_operand PARAMS ((FILE *, rtx, int));
-extern int s390_adjust_cost PARAMS ((rtx, rtx, rtx, int));
extern int s390_stop_dump_lit_p PARAMS ((rtx));
extern void s390_dump_literal_pool PARAMS ((rtx, rtx));
extern void s390_trampoline_template PARAMS ((FILE *));
#include "debug.h"
+static int s390_adjust_cost PARAMS ((rtx, rtx, rtx, int));
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE s390_function_prologue
#undef TARGET_ASM_CLOSE_PAREN
#define TARGET_ASM_CLOSE_PAREN ""
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST s390_adjust_cost
+
struct gcc_target targetm = TARGET_INITIALIZER;
extern int reload_completed;
register of a memory reference, at least 4 cycles need to pass
between setting and using the register to avoid pipeline stalls. */
-int
+static int
s390_adjust_cost (insn, link, dep_insn, cost)
rtx insn;
rtx link;
{"tmxx_operand", { CONST_INT, MEM }},
-/* A C statement (sans semicolon) to update the integer variable COST
- based on the relationship between INSN that is dependent on
- DEP_INSN through the dependence LINK. The default is to make no
- adjustment to COST. This can be used for example to specify to
- the scheduler that an output- or anti-dependence does not incur
- the same cost as a data-dependence. */
-
-#define ADJUST_COST(insn, link, dep_insn, cost) \
- (cost) = s390_adjust_cost (insn, link, dep_insn, cost)
-
-
/* Constant Pool for all symbols operands which are changed with
force_const_mem during insn generation (expand_insn). */
static void sh_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void sh_insert_attributes PARAMS ((tree, tree *));
static void sh_asm_named_section PARAMS ((const char *, unsigned int));
+static int sh_adjust_cost PARAMS ((rtx, rtx, rtx, int));
\f
/* Initialize the GCC target structure. */
#undef TARGET_VALID_DECL_ATTRIBUTE
#undef TARGET_INSERT_ATTRIBUTES
#define TARGET_INSERT_ATTRIBUTES sh_insert_attributes
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST sh_adjust_cost
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Print the operand address in x to the stream. */
/* ??? Perhaps we should be using default_coff_asm_named_section. */
fprintf (asm_out_file, "\t.section %s\n", name);
}
+
+/* A C statement (sans semicolon) to update the integer variable COST
+ based on the relationship between INSN that is dependent on
+ DEP_INSN through the dependence LINK. The default is to make no
+ adjustment to COST. This can be used for example to specify to
+ the scheduler that an output- or anti-dependence does not incur
+ the same cost as a data-dependence. */
+static int
+sh_adjust_cost (insn, link, dep_insn, cost)
+ rtx insn;
+ rtx link;
+ rtx dep_insn;
+ int cost;
+{
+ rtx reg;
+
+ if (GET_CODE(insn) == CALL_INSN)
+ {
+ /* The only input for a call that is timing-critical is the
+ function's address. */
+ rtx call = PATTERN (insn);
+
+ if (GET_CODE (call) == PARALLEL)
+ call = XVECEXP (call, 0 ,0);
+ if (GET_CODE (call) == SET)
+ call = SET_SRC (call);
+ if (GET_CODE (call) == CALL && GET_CODE (XEXP (call, 0)) == MEM
+ && ! reg_set_p (XEXP (XEXP (call, 0), 0), dep_insn))
+ cost = 0;
+ }
+ /* All sfunc calls are parallels with at least four components.
+ Exploit this to avoid unnecessary calls to sfunc_uses_reg. */
+ else if (GET_CODE (PATTERN (insn)) == PARALLEL
+ && XVECLEN (PATTERN (insn), 0) >= 4
+ && (reg = sfunc_uses_reg (insn)))
+ {
+ /* Likewise, the most timing critical input for an sfuncs call
+ is the function address. However, sfuncs typically start
+ using their arguments pretty quickly.
+ Assume a four cycle delay before they are needed. */
+ if (! reg_set_p (reg, dep_insn))
+ cost -= TARGET_SUPERSCALAR ? 40 : 4;
+ }
+ /* Adjust load_si / pcload_si type insns latency. Use the known
+ nominal latency and form of the insn to speed up the check. */
+ else if (cost == 3
+ && GET_CODE (PATTERN (dep_insn)) == SET
+ /* Latency for dmpy type insns is also 3, so check the that
+ it's actually a move insn. */
+ && general_movsrc_operand (SET_SRC (PATTERN (dep_insn)), SImode))
+ cost = 2;
+ else if (cost == 30
+ && GET_CODE (PATTERN (dep_insn)) == SET
+ && GET_MODE (SET_SRC (PATTERN (dep_insn))) == SImode)
+ cost = 20;
+
+ return cost;
+}
clear if this would give better code. If implemented, should check for
compatibility problems. */
-/* A C statement (sans semicolon) to update the integer variable COST
- based on the relationship between INSN that is dependent on
- DEP_INSN through the dependence LINK. The default is to make no
- adjustment to COST. This can be used for example to specify to
- the scheduler that an output- or anti-dependence does not incur
- the same cost as a data-dependence. */
-
-#define ADJUST_COST(insn,link,dep_insn,cost) \
-do { \
- rtx reg; \
- \
- if (GET_CODE(insn) == CALL_INSN) \
- { \
- /* The only input for a call that is timing-critical is the \
- function's address. */ \
- rtx call = PATTERN (insn); \
- \
- if (GET_CODE (call) == PARALLEL) \
- call = XVECEXP (call, 0 ,0); \
- if (GET_CODE (call) == SET) \
- call = SET_SRC (call); \
- if (GET_CODE (call) == CALL && GET_CODE (XEXP (call, 0)) == MEM \
- && ! reg_set_p (XEXP (XEXP (call, 0), 0), dep_insn)) \
- (cost) = 0; \
- } \
- /* All sfunc calls are parallels with at least four components. \
- Exploit this to avoid unnecessary calls to sfunc_uses_reg. */ \
- else if (GET_CODE (PATTERN (insn)) == PARALLEL \
- && XVECLEN (PATTERN (insn), 0) >= 4 \
- && (reg = sfunc_uses_reg (insn))) \
- { \
- /* Likewise, the most timing critical input for an sfuncs call \
- is the function address. However, sfuncs typically start \
- using their arguments pretty quickly. \
- Assume a four cycle delay before they are needed. */ \
- if (! reg_set_p (reg, dep_insn)) \
- cost -= TARGET_SUPERSCALAR ? 40 : 4; \
- } \
- /* Adjust load_si / pcload_si type insns latency. Use the known \
- nominal latency and form of the insn to speed up the check. */ \
- else if (cost == 3 \
- && GET_CODE (PATTERN (dep_insn)) == SET \
- /* Latency for dmpy type insns is also 3, so check the that \
- it's actually a move insn. */ \
- && general_movsrc_operand (SET_SRC (PATTERN (dep_insn)), SImode))\
- cost = 2; \
- else if (cost == 30 \
- && GET_CODE (PATTERN (dep_insn)) == SET \
- && GET_MODE (SET_SRC (PATTERN (dep_insn))) == SImode) \
- cost = 20; \
-} while (0) \
-
#define SH_DYNAMIC_SHIFT_COST \
(TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (TARGET_SMALLCODE ? 1 : 2) : 20)
#endif /* ARGS_SIZE_RTX */
#endif /* TREE_CODE */
-extern void ultrasparc_sched_init PARAMS ((FILE *, int));
extern void load_pic_register PARAMS ((void));
extern void order_regs_for_local_alloc PARAMS ((void));
extern int compute_frame_size PARAMS ((int, int));
extern int check_pic PARAMS ((int));
extern int short_branch PARAMS ((int, int));
extern int sparc_flat_epilogue_delay_slots PARAMS ((void));
-extern int sparc_issue_rate PARAMS ((void));
extern unsigned long sparc_flat_compute_frame_size PARAMS ((int));
extern void sparc_function_profiler PARAMS ((FILE *, int));
extern void sparc_function_block_profiler PARAMS ((FILE *, int));
extern void sparc_initialize_trampoline PARAMS ((rtx, rtx, rtx));
extern void sparc64_initialize_trampoline PARAMS ((rtx, rtx, rtx));
extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
-extern void ultrasparc_sched_reorder PARAMS ((FILE *, int, rtx *, int));
-extern int ultrasparc_variable_issue PARAMS ((rtx));
extern void sparc_defer_case_vector PARAMS ((rtx, rtx, int));
extern void sparc_emit_set_const32 PARAMS ((rtx, rtx));
extern void sparc_emit_set_const64 PARAMS ((rtx, rtx));
extern int register_ok_for_ldd PARAMS ((rtx));
extern int registers_ok_for_ldd_peep PARAMS ((rtx, rtx));
extern int sparc_flat_eligible_for_epilogue_delay PARAMS ((rtx, int));
-extern int sparc_adjust_cost PARAMS ((rtx, rtx, rtx, int));
extern int v9_regcmp_p PARAMS ((enum rtx_code));
extern char *sparc_v8plus_shift PARAMS ((rtx *, rtx, const char *));
/* Function used for V8+ code generation. Returns 1 if the high
static void sparc_nonflat_function_prologue PARAMS ((FILE *, HOST_WIDE_INT,
int));
static void sparc_elf_asm_named_section PARAMS ((const char *, unsigned int));
+
+static void ultrasparc_sched_reorder PARAMS ((FILE *, int, rtx *, int));
+static int ultrasparc_variable_issue PARAMS ((rtx));
+static void ultrasparc_sched_init PARAMS ((void));
+
+static int sparc_adjust_cost PARAMS ((rtx, rtx, rtx, int));
+static int sparc_issue_rate PARAMS ((void));
+static int sparc_variable_issue PARAMS ((FILE *, int, rtx, int));
+static void sparc_sched_init PARAMS ((FILE *, int, int));
+static int sparc_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
\f
/* Option handling. */
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE sparc_output_function_epilogue
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST sparc_adjust_cost
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE sparc_issue_rate
+#undef TARGET_SCHED_VARIABLE_ISSUE
+#define TARGET_SCHED_VARIABLE_ISSUE sparc_variable_issue
+#undef TARGET_SCHED_INIT
+#define TARGET_SCHED_INIT sparc_sched_init
+#undef TARGET_SCHED_REORDER
+#define TARGET_SCHED_REORDER sparc_sched_reorder
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Validate and override various options, and do some machine dependent
#undef SLOW_FP
}
-int
+static int
sparc_adjust_cost(insn, link, dep, cost)
rtx insn;
rtx link;
}
/* Init our data structures for this current block. */
-void
-ultrasparc_sched_init (dump, sched_verbose)
- FILE *dump ATTRIBUTE_UNUSED;
- int sched_verbose ATTRIBUTE_UNUSED;
+static void
+ultrasparc_sched_init ()
{
memset ((char *) ultra_pipe_hist, 0, sizeof ultra_pipe_hist);
ultra_cur_hist = 0;
ultra_pipe.free_slot_mask = 0xf;
}
+static void
+sparc_sched_init (dump, sched_verbose, max_ready)
+ FILE *dump ATTRIBUTE_UNUSED;
+ int sched_verbose ATTRIBUTE_UNUSED;
+ int max_ready ATTRIBUTE_UNUSED;
+{
+ if (sparc_cpu == PROCESSOR_ULTRASPARC)
+ ultrasparc_sched_init ();
+}
+
/* INSN has been scheduled, update pipeline commit state
and return how many instructions are still to be
scheduled in this group. */
-int
+static int
ultrasparc_variable_issue (insn)
rtx insn;
{
return left_to_fire;
}
+static int
+sparc_variable_issue (dump, sched_verbose, insn, cim)
+ FILE *dump ATTRIBUTE_UNUSED;
+ int sched_verbose ATTRIBUTE_UNUSED;
+ rtx insn;
+ int cim;
+{
+ if (sparc_cpu == PROCESSOR_ULTRASPARC)
+ return ultrasparc_variable_issue (INSN);
+ else
+ return cim - 1;
+}
+
/* In actual_hazard_this_instance, we may have yanked some
instructions from the ready list due to conflict cost
adjustments. If so, and such an insn was in our pipeline
}
}
-void
+static void
ultrasparc_sched_reorder (dump, sched_verbose, ready, n_ready)
FILE *dump;
int sched_verbose;
}
}
-int
+static int
+sparc_sched_reorder (dump, sched_verbose, ready, n_readyp, clock)
+ FILE *dump;
+ int sched_verbose;
+ rtx *ready;
+ int *n_readyp;
+ int clock;
+{
+ if (sparc_cpu == PROCESSOR_ULTRASPARC)
+ ultrasparc_sched_reorder (dump, sched_verbose, ready, *n_readyp);
+ return sparc_issue_rate ();
+}
+
+static int
sparc_issue_rate ()
{
switch (sparc_cpu)
case FIX: \
return 19;
-#define ISSUE_RATE sparc_issue_rate()
-
-/* Adjust the cost of dependencies. */
-#define ADJUST_COST(INSN,LINK,DEP,COST) \
- (COST) = sparc_adjust_cost(INSN, LINK, DEP, COST)
-
-#define MD_SCHED_INIT(DUMP, SCHED_VERBOSE, MAX_READY) \
- if (sparc_cpu == PROCESSOR_ULTRASPARC) \
- ultrasparc_sched_init (DUMP, SCHED_VERBOSE)
-
-#define MD_SCHED_REORDER(DUMP, SCHED_VERBOSE, READY, N_READY, CLOCK, CIM) \
-do { \
- if (sparc_cpu == PROCESSOR_ULTRASPARC) \
- ultrasparc_sched_reorder (DUMP, SCHED_VERBOSE, READY, N_READY); \
- CIM = issue_rate; \
-} while (0)
-
-#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \
-do { \
- if (sparc_cpu == PROCESSOR_ULTRASPARC) \
- (CAN_ISSUE_MORE) = ultrasparc_variable_issue (INSN); \
- else \
- (CAN_ISSUE_MORE)--; \
-} while (0)
-
/* Conditional branches with empty delay slots have a length of two. */
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
do { \
* Addressing Modes:: Defining addressing modes valid for memory operands.
* Condition Code:: Defining how insns update the condition code.
* Costs:: Defining relative costs of different operations.
+* Scheduling:: Adjusting the behavior of the instruction scheduler.
* Sections:: Dividing storage into text, data, and other sections.
* PIC:: Macros for position independent code.
* Assembler Format:: Defining how to write insns and pseudo-ops to output.
try when searching for local header files. @code{LOCAL_INCLUDE_DIR}
comes before @code{SYSTEM_INCLUDE_DIR} in the search order.
-Cross compilers do not use this macro and do not search either
-@file{/usr/local/include} or its replacement.
+Cross compilers do not search either @file{/usr/local/include} or its
+replacement.
@findex MODIFY_TARGET_NAME
@item MODIFY_TARGET_NAME
@item CONDITIONAL_REGISTER_USAGE
Zero or more C statements that may conditionally modify five variables
@code{fixed_regs}, @code{call_used_regs}, @code{global_regs},
-(these three are of type @code{char []}), @code{reg_names} (of type
-@code{const char * []}) and @code{reg_class_contents} (of type
-@code{HARD_REG_SET}).
-Before the macro is called @code{fixed_regs}, @code{call_used_regs}
-@code{reg_class_contents} and @code{reg_names} have been initialized
+@code{reg_names}, and @code{reg_class_contents}, to take into account
+any dependence of these register sets on target flags. The first three
+of these are of type @code{char []} (interpreted as Boolean vectors).
+@code{global_regs} is a @code{const char *[]}, and
+@code{reg_class_contents} is a @code{HARD_REG_SET}. Before the macro is
+called, @code{fixed_regs}, @code{call_used_regs},
+@code{reg_class_contents}, and @code{reg_names} have been initialized
from @code{FIXED_REGISTERS}, @code{CALL_USED_REGISTERS},
-@code{REG_CLASS_CONTENTS} and @code{REGISTER_NAMES}, respectively,
+@code{REG_CLASS_CONTENTS}, and @code{REGISTER_NAMES}, respectively.
@code{global_regs} has been cleared, and any @option{-ffixed-@var{reg}},
-@option{-fcall-used-@var{reg}} and @option{-fcall-saved-@var{reg}} command
-options have been applied.
-
-This is necessary in case the fixed or call-clobbered registers depend
-on target flags.
+@option{-fcall-used-@var{reg}} and @option{-fcall-saved-@var{reg}}
+command options have been applied.
You need not define this macro if it has no work to do.
@findex current_function_is_leaf
@findex current_function_uses_only_leaf_regs
-Normally, @code{TARGET_ASM_FUNCTION_PROLOGUE} and
-@code{TARGET_ASM_FUNCTION_EPILOGUE} must treat leaf functions specially.
-They can test the C variable @code{current_function_is_leaf} which is
-nonzero for leaf functions. @code{current_function_is_leaf} is set
-prior to local register allocation and is valid for the remaining
+@code{TARGET_ASM_FUNCTION_PROLOGUE} and
+@code{TARGET_ASM_FUNCTION_EPILOGUE} must usually treat leaf functions
+specially. They can test the C variable @code{current_function_is_leaf}
+which is nonzero for leaf functions. @code{current_function_is_leaf} is
+set prior to local register allocation and is valid for the remaining
compiler passes. They can also test the C variable
@code{current_function_uses_only_leaf_regs} which is nonzero for leaf
functions which only use leaf registers.
* Caller Saves::
* Function Entry::
* Profiling::
-* Inlining::
-* Tail Calling::
+* Inlining and Tail Calls::
@end menu
@node Frame Layout
@end table
-@node Inlining
-@subsection Permitting inlining of functions with attributes
+@node Inlining and Tail Calls
+@subsection Permitting inlining and tail calls
@cindex inlining
-By default if a function has a target specific attribute attached to it,
-it will not be inlined. This behaviour can be overridden if the target
-defines the @samp{FUNCTION_ATTRIBUTE_INLINABLE_P} macro. This macro
-takes one argument, a @samp{DECL} describing the function. It should
-return non-zero if the function can be inlined, otherwise it should
-return 0.
-
-@node Tail Calling
-@subsection Permitting tail calls to functions
-@cindex tail calls
-@cindex sibling calls
-
@table @code
+@findex FUNCTION_ATTRIBUTE_INLINABLE_P
+@item FUNCTION_ATTRIBUTE_INLINABLE_P (@var{decl})
+A C expression that evaluates to true if it is ok to inline @var{decl}
+into the current function, despite its having target-specific
+attributes. By default, if a function has a target specific attribute
+attached to it, it will not be inlined.
+
@findex FUNCTION_OK_FOR_SIBCALL
@item FUNCTION_OK_FOR_SIBCALL (@var{decl})
A C expression that evaluates to true if it is ok to perform a sibling
-call to @var{decl}.
+call to @var{decl} from the current function.
It is not uncommon for limitations of calling conventions to prevent
tail calls to functions outside the current unit of translation, or
Define this macro if it is as good or better for a function to call
itself with an explicit address than to call an address kept in a
register.
-
-@findex ADJUST_COST
-@item ADJUST_COST (@var{insn}, @var{link}, @var{dep_insn}, @var{cost})
-A C statement (sans semicolon) to update the integer variable @var{cost}
-based on the relationship between @var{insn} that is dependent on
-@var{dep_insn} through the dependence @var{link}. The default is to
-make no adjustment to @var{cost}. This can be used for example to
-specify to the scheduler that an output- or anti-dependence does not
-incur the same cost as a data-dependence.
-
-@findex ADJUST_PRIORITY
-@item ADJUST_PRIORITY (@var{insn})
-A C statement (sans semicolon) to update the integer scheduling
-priority @code{INSN_PRIORITY(@var{insn})}. Reduce the priority
-to execute the @var{insn} earlier, increase the priority to execute
-@var{insn} later. Do not define this macro if you do not need to
-adjust the scheduling priorities of insns.
@end table
+@node Scheduling
+@section Adjusting the Instruction Scheduler
+
+The instruction scheduler may need a fair amount of machine-specific
+adjustment in order to produce good code. GCC provides several target
+hooks for this purpose. It is usually enough to define just a few of
+them: try the first ones in this list first.
+
+@deftypefn {Target Hook} int TARGET_SCHED_ISSUE_RATE (void)
+This hook returns the maximum number of instructions that can ever issue
+at the same time on the target machine. The default is one. This value
+must be constant over the entire compilation. If you need it to vary
+depending on what the instructions are, you must use
+@samp{TARGET_SCHED_VARIABLE_ISSUE}.
+@end deftypefn
+
+@deftypefn {Target Hook} int TARGET_SCHED_VARIABLE_ISSUE (FILE *@var{file}, int @var{verbose}, rtx @var{insn}, int @var{more})
+This hook is executed by the scheduler after it has scheduled an insn
+from the ready list. It should return the number of insns which can
+still be issued in the current cycle. Normally this is
+@samp{@w{@var{more} - 1}}. You should define this hook if some insns
+take more machine resources than others, so that fewer insns can follow
+them in the same cycle. @var{file} is either a null pointer, or a stdio
+stream to write any debug output to. @var{verbose} is the verbose level
+provided by @option{-fsched-verbose-@var{n}}. @var{insn} is the
+instruction that was scheduled.
+@end deftypefn
+
+@deftypefn {Target Hook} int TARGET_SCHED_ADJUST_COST (rtx @var{insn}, rtx @var{link}, rtx @var{dep_insn}, int @var{cost})
+This function corrects the value of @var{cost} based on the relationship
+between @var{insn} and @var{dep_insn} through the dependence @var{link}.
+It should return the new value. The default is to make no adjustment to
+@var{cost}. This can be used for example to specify to the scheduler
+that an output- or anti-dependence does not incur the same cost as a
+data-dependence.
+@end deftypefn
+
+@deftypefn {Target Hook} int TARGET_SCHED_ADJUST_PRIORITY (rtx @var{insn}, int @var{priority})
+This hook adjusts the integer scheduling priority @var{priority} of
+@var{insn}. It should return the new priority. Reduce the priority to
+execute @var{insn} earlier, increase the priority to execute @var{insn}
+later. Do not define this hook if you do not need to adjust the
+scheduling priorities of insns.
+@end deftypefn
+
+@deftypefn {Target Hook} int TARGET_SCHED_REORDER (FILE *@var{file}, int @var{verbose}, rtx *@var{ready}, int *@var{n_readyp}, int @var{clock})
+This hook is executed by the scheduler after it has scheduled the ready
+list, to allow the machine description to reorder it (for example to
+combine two small instructions together on @samp{VLIW} machines).
+@var{file} is either a null pointer, or a stdio stream to write any
+debug output to. @var{verbose} is the verbose level provided by
+@option{-fsched-verbose-@var{n}}. @var{ready} is a pointer to the ready
+list of instructions that are ready to be scheduled. @var{n_readyp} is
+a pointer to the number of elements in the ready list. The scheduler
+reads the ready list in reverse order, starting with
+@var{ready}[@var{*n_readyp}-1] and going to @var{ready}[0]. @var{clock}
+is the timer tick of the scheduler. You may modify the ready list and
+the number of ready insns. The return value is the number of insns that
+can issue this cycle; normally this is just @code{issue_rate}. See also
+@samp{TARGET_SCHED_REORDER2}.
+@end deftypefn
+
+@deftypefn {Target Hook} int TARGET_SCHED_REORDER2 (FILE *@var{file}, int @var{verbose}, rtx *@var{ready}, int *@var{n_ready}, @var{clock})
+Like @samp{TARGET_SCHED_REORDER}, but called at a different time. That
+function is called whenever the scheduler starts a new cycle. This one
+is called once per iteration over a cycle, immediately after
+@samp{TARGET_SCHED_VARIABLE_ISSUE}; it can reorder the ready list and
+return the number of insns to be scheduled in the same cycle. Defining
+this hook can be useful if there are frequent situations where
+scheduling one insn causes other insns to become ready in the same
+cycle. These other insns can then be taken into account properly.
+@end deftypefn
+
+@deftypefn {Target Hook} void TARGET_SCHED_INIT (FILE *@var{file}, int @var{verbose}, int @var{max_ready})
+This hook is executed by the scheduler at the beginning of each block of
+instructions that are to be scheduled. @var{file} is either a null
+pointer, or a stdio stream to write any debug output to. @var{verbose}
+is the verbose level provided by @option{-fsched-verbose-@var{n}}.
+@var{max_ready} is the maximum number of insns in the current scheduling
+region that can be live at the same time. This can be used to allocate
+scratch space if it is needed, e.g. by @samp{TARGET_SCHED_REORDER}.
+@end deftypefn
+
+@deftypefn {Target Hook} void TARGET_SCHED_FINISH (FILE *@var{file}, int @var{verbose})
+This hook is executed by the scheduler at the end of each block of
+instructions that are to be scheduled. It can be used to perform
+cleanup of any actions done by the other scheduling hooks. @var{file}
+is either a null pointer, or a stdio stream to write any debug output
+to. @var{verbose} is the verbose level provided by
+@option{-fsched-verbose-@var{n}}.
+@end deftypefn
+
+@deftypefn {Target Hook} rtx TARGET_SCHED_CYCLE_DISPLAY (int @var{clock}, rtx @var{last})
+This hook is called in verbose mode only, at the beginning of each pass
+over a basic block. It should insert an insn into the chain after
+@var{last}, which has no effect, but records the value @var{clock} in
+RTL dumps and assembly output. Define this hook only if you need this
+level of detail about what the scheduler is doing.
+@end deftypefn
+
@node Sections
@section Dividing the Output into Sections (Texts, Data, @dots{})
@c the above section title is WAY too long. maybe cut the part between
first variant.
If this macro is defined, you may use constructs of the form
-@samp{@{option0|option1|option2@dots{}@}} in the output
-templates of patterns (@pxref{Output Template}) or in the first argument
-of @code{asm_fprintf}. This construct outputs @samp{option0},
-@samp{option1} or @samp{option2}, etc., if the value of
-@code{ASSEMBLER_DIALECT} is zero, one or two, etc. Any special
-characters within these strings retain their usual meaning.
+@smallexample
+@samp{@{option0|option1|option2@dots{}@}}
+@end smallexample
+@noindent
+in the output templates of patterns (@pxref{Output Template}) or in the
+first argument of @code{asm_fprintf}. This construct outputs
+@samp{option0}, @samp{option1}, @samp{option2}, etc., if the value of
+@code{ASSEMBLER_DIALECT} is zero, one, two, etc. Any special characters
+within these strings retain their usual meaning. If there are fewer
+alternatives within the braces than the value of
+@code{ASSEMBLER_DIALECT}, the construct outputs nothing.
If you do not define this macro, the characters @samp{@{}, @samp{|} and
@samp{@}} do not have any special meaning when used in templates or
other compilers for the same target. In general, we discourage
definition of target-specific pragmas for GCC@.
-If the pragma can be implemented by attributes then the macro
-@samp{INSERT_ATTRIBUTES} might be a useful one to define as well.
+If the pragma can be implemented by attributes then you should consider
+defining @samp{INSERT_ATTRIBUTES} as well.
Preprocessor macros that appear on pragma lines are not expanded. All
@samp{#pragma} directives that do not match any registered pragma are
A C statement that adds to @var{clobbers} @code{STRING_CST} trees for
any hard regs the port wishes to automatically clobber for all asms.
-@findex ISSUE_RATE
-@item ISSUE_RATE
-A C expression that returns how many instructions can be issued at the
-same time if the machine is a superscalar machine.
-
-@findex MD_SCHED_INIT
-@item MD_SCHED_INIT (@var{file}, @var{verbose}, @var{max_ready})
-A C statement which is executed by the scheduler at the
-beginning of each block of instructions that are to be scheduled.
-@var{file} is either a null pointer, or a stdio stream to write any
-debug output to. @var{verbose} is the verbose level provided by
-@option{-fsched-verbose-@var{n}}. @var{max_ready} is the maximum number
-of insns in the current scheduling region that can be live at the same
-time. This can be used to allocate scratch space if it is needed.
-
-@findex MD_SCHED_FINISH
-@item MD_SCHED_FINISH (@var{file}, @var{verbose})
-A C statement which is executed by the scheduler at the end of each block
-of instructions that are to be scheduled. It can be used to perform
-cleanup of any actions done by the other scheduling macros.
-@var{file} is either a null pointer, or a stdio stream to write any
-debug output to. @var{verbose} is the verbose level provided by
-@option{-fsched-verbose-@var{n}}.
-
-@findex MD_SCHED_REORDER
-@item MD_SCHED_REORDER (@var{file}, @var{verbose}, @var{ready}, @var{n_ready}, @var{clock}, @var{can_issue_more})
-A C statement which is executed by the scheduler after it
-has scheduled the ready list to allow the machine description to reorder
-it (for example to combine two small instructions together on
-@samp{VLIW} machines). @var{file} is either a null pointer, or a stdio
-stream to write any debug output to. @var{verbose} is the verbose level
-provided by @option{-fsched-verbose-@var{n}}. @var{ready} is a pointer to
-the ready list of instructions that are ready to be scheduled.
-@var{n_ready} is the number of elements in the ready list. The
-scheduler reads the ready list in reverse order, starting with
-@var{ready}[@var{n_ready}-1] and going to @var{ready}[0]. @var{clock}
-is the timer tick of the scheduler. @var{can_issue_more} is an output
-parameter that is set to the number of insns that can issue this clock;
-normally this is just @code{issue_rate}. See also @samp{MD_SCHED_REORDER2}.
-
-@findex MD_SCHED_REORDER2
-@item MD_SCHED_REORDER2 (@var{file}, @var{verbose}, @var{ready}, @var{n_ready}, @var{clock}, @var{can_issue_more})
-Like @samp{MD_SCHED_REORDER}, but called at a different time. While the
-@samp{MD_SCHED_REORDER} macro is called whenever the scheduler starts a
-new cycle, this macro is used immediately after @samp{MD_SCHED_VARIABLE_ISSUE}
-is called; it can reorder the ready list and set @var{can_issue_more} to
-determine whether there are more insns to be scheduled in the same cycle.
-Defining this macro can be useful if there are frequent situations where
-scheduling one insn causes other insns to become ready in the same cycle,
-these other insns can then be taken into account properly.
-
-@findex MD_SCHED_VARIABLE_ISSUE
-@item MD_SCHED_VARIABLE_ISSUE (@var{file}, @var{verbose}, @var{insn}, @var{more})
-A C statement which is executed by the scheduler after it
-has scheduled an insn from the ready list. @var{file} is either a null
-pointer, or a stdio stream to write any debug output to. @var{verbose}
-is the verbose level provided by @option{-fsched-verbose-@var{n}}.
-@var{insn} is the instruction that was scheduled. @var{more} is the
-number of instructions that can be issued in the current cycle. The
-@samp{MD_SCHED_VARIABLE_ISSUE} macro is responsible for updating the
-value of @var{more} (typically by @samp{@var{more}--}).
-
@findex MAX_INTEGER_COMPUTATION_MODE
@item MAX_INTEGER_COMPUTATION_MODE
Define this to the largest integer machine mode which can be used for
A C expression to cancel any machine dependent modifications in
converting code to conditional execution in the basic blocks
@code{TEST_BB}, @code{THEN_BB}, @code{ELSE_BB}, and @code{JOIN_BB}.
+@end table
@deftypefn {Target Hook} void TARGET_INIT_BUILTINS ()
Define this hook if you have any machine-specific built-in functions
To create a built-in function, call the function @code{builtin_function}
which is defined by the language front end. You can use any type nodes set
up by @code{build_common_tree_nodes} and @code{build_common_tree_nodes_2};
-only language front ends that use these two functions will use
+only language front ends that use those two functions will call
@samp{TARGET_INIT_BUILTINS}.
@end deftypefn
built-in function.
@end deftypefn
+@table @code
@findex MD_CAN_REDIRECT_BRANCH
@item MD_CAN_REDIRECT_BRANCH(@var{branch1}, @var{branch2})
#include "toplev.h"
#include "recog.h"
#include "sched-int.h"
+#include "target.h"
#ifdef INSN_SCHEDULING
static int issue_rate;
-#ifndef ISSUE_RATE
-#define ISSUE_RATE 1
-#endif
-
/* sched-verbose controls the amount of debugging output the
scheduler prints. It is controlled by -fsched-verbose=N:
N>0 and no -DSR : the output is directed to stderr.
if (LINK_COST_FREE (link))
cost = 0;
-#ifdef ADJUST_COST
- else if (!LINK_COST_ZERO (link))
+ else if (!LINK_COST_ZERO (link) && targetm.sched.adjust_cost)
{
- int ncost = cost;
+ int ncost = (*targetm.sched.adjust_cost) (used, link, insn, cost);
- ADJUST_COST (used, link, insn, ncost);
if (ncost < 1)
{
LINK_COST_FREE (link) = 1;
LINK_COST_ZERO (link) = 1;
cost = ncost;
}
-#endif
+
return cost;
}
HAIFA_INLINE static void
adjust_priority (prev)
- rtx prev ATTRIBUTE_UNUSED;
+ rtx prev;
{
/* ??? There used to be code here to try and estimate how an insn
affected register lifetimes, but it did it by looking at REG_DEAD
Revisit when we have a machine model to work with and not before. */
-#ifdef ADJUST_PRIORITY
- ADJUST_PRIORITY (prev);
-#endif
+ if (targetm.sched.adjust_priority)
+ INSN_PRIORITY (prev) =
+ (*targetm.sched.adjust_priority) (prev, INSN_PRIORITY (prev));
}
/* Clock at which the previous instruction was issued. */
clear_units ();
/* Allocate the ready list. */
- ready.veclen = rgn_n_insns + 1 + ISSUE_RATE;
+ ready.veclen = rgn_n_insns + 1 + issue_rate;
ready.first = ready.veclen - 1;
ready.vec = (rtx *) xmalloc (ready.veclen * sizeof (rtx));
ready.n_ready = 0;
(*current_sched_info->init_ready_list) (&ready);
-#ifdef MD_SCHED_INIT
- MD_SCHED_INIT (sched_dump, sched_verbose, ready.veclen);
-#endif
+ if (targetm.sched.md_init)
+ (*targetm.sched.md_init) (sched_dump, sched_verbose, ready.veclen);
/* No insns scheduled in this block yet. */
last_scheduled_insn = 0;
list. */
queue_to_ready (&ready);
-#ifdef HAVE_cycle_display
- if (HAVE_cycle_display)
- last = emit_insn_after (gen_cycle_display (GEN_INT (clock_var)), last);
-#endif
+ if (sched_verbose && targetm.sched.cycle_display)
+ last = (*targetm.sched.cycle_display) (clock_var, last);
if (ready.n_ready == 0)
abort ();
/* Allow the target to reorder the list, typically for
better instruction bundling. */
-#ifdef MD_SCHED_REORDER
- MD_SCHED_REORDER (sched_dump, sched_verbose, ready_lastpos (&ready),
- ready.n_ready, clock_var, can_issue_more);
-#else
- can_issue_more = issue_rate;
-#endif
+ if (targetm.sched.reorder)
+ can_issue_more =
+ (*targetm.sched.reorder) (sched_dump, sched_verbose,
+ ready_lastpos (&ready),
+ &ready.n_ready, clock_var);
+ else
+ can_issue_more = issue_rate;
if (sched_verbose)
{
last_scheduled_insn = insn;
last = move_insn (insn, last);
-#ifdef MD_SCHED_VARIABLE_ISSUE
- MD_SCHED_VARIABLE_ISSUE (sched_dump, sched_verbose, insn,
- can_issue_more);
-#else
- can_issue_more--;
-#endif
+ if (targetm.sched.variable_issue)
+ can_issue_more =
+ (*targetm.sched.variable_issue) (sched_dump, sched_verbose,
+ insn, can_issue_more);
+ else
+ can_issue_more--;
schedule_insn (insn, &ready, clock_var);
next:
- ;
-#ifdef MD_SCHED_REORDER2
- /* Sort the ready list based on priority. */
- if (ready.n_ready > 0)
- ready_sort (&ready);
- MD_SCHED_REORDER2 (sched_dump, sched_verbose,
- ready.n_ready ? ready_lastpos (&ready) : NULL,
- ready.n_ready, clock_var, can_issue_more);
-#endif
+ if (targetm.sched.reorder2)
+ {
+ /* Sort the ready list based on priority. */
+ if (ready.n_ready > 0)
+ ready_sort (&ready);
+ can_issue_more =
+ (*targetm.sched.reorder2) (sched_dump,sched_verbose,
+ ready.n_ready
+ ? ready_lastpos (&ready) : NULL,
+ &ready.n_ready, clock_var);
+ }
}
/* Debug info. */
visualize_scheduled_insns (clock_var);
}
-#ifdef MD_SCHED_FINISH
- MD_SCHED_FINISH (sched_dump, sched_verbose);
-#endif
+ if (targetm.sched.md_finish)
+ (*targetm.sched.md_finish) (sched_dump, sched_verbose);
/* Debug info. */
if (sched_verbose)
? stderr : dump_file);
/* Initialize issue_rate. */
- issue_rate = ISSUE_RATE;
+ if (targetm.sched.issue_rate)
+ issue_rate = (*targetm.sched.issue_rate) ();
+ else
+ issue_rate = 1;
/* We use LUID 0 for the fake insn (UID 0) which holds dependencies for
pseudos which do not cross calls. */
TARGET_ASM_CONSTRUCTOR, \
TARGET_ASM_DESTRUCTOR}
+/* Scheduler hooks. All of these default to null pointers, which
+ haifa-sched.c looks for and handles. */
+#define TARGET_SCHED_ADJUST_COST 0
+#define TARGET_SCHED_ADJUST_PRIORITY 0
+#define TARGET_SCHED_ISSUE_RATE 0
+#define TARGET_SCHED_VARIABLE_ISSUE 0
+#define TARGET_SCHED_INIT 0
+#define TARGET_SCHED_FINISH 0
+#define TARGET_SCHED_REORDER 0
+#define TARGET_SCHED_REORDER2 0
+#define TARGET_SCHED_CYCLE_DISPLAY 0
+
+#define TARGET_SCHED {TARGET_SCHED_ADJUST_COST, \
+ TARGET_SCHED_ADJUST_PRIORITY, \
+ TARGET_SCHED_ISSUE_RATE, \
+ TARGET_SCHED_VARIABLE_ISSUE, \
+ TARGET_SCHED_INIT, \
+ TARGET_SCHED_FINISH, \
+ TARGET_SCHED_REORDER, \
+ TARGET_SCHED_REORDER2, \
+ TARGET_SCHED_CYCLE_DISPLAY}
+
/* All in tree.c. */
#define TARGET_MERGE_DECL_ATTRIBUTES merge_decl_attributes
#define TARGET_MERGE_TYPE_ATTRIBUTES merge_type_attributes
#define TARGET_INITIALIZER \
{ \
TARGET_ASM_OUT, \
+ TARGET_SCHED, \
TARGET_MERGE_DECL_ATTRIBUTES, \
TARGET_MERGE_TYPE_ATTRIBUTES, \
TARGET_VALID_DECL_ATTRIBUTE, \
to gradually reduce the amount of conditional compilation that is
scattered throughout GCC. */
-/* Forward declaration for the benefit of prototypes. */
-struct rtx_def;
-
struct gcc_target
{
/* Functions that output assembler for the target. */
void (* named_section) PARAMS ((const char *, unsigned int));
/* Output a constructor for a symbol with a given priority. */
- void (* constructor) PARAMS ((struct rtx_def *, int));
+ void (* constructor) PARAMS ((rtx, int));
/* Output a destructor for a symbol with a given priority. */
- void (* destructor) PARAMS ((struct rtx_def *, int));
+ 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));
void (* init_builtins) PARAMS ((void));
/* Expand a target-specific builtin. */
- struct rtx_def * (* expand_builtin) PARAMS ((tree exp,
- struct rtx_def *target,
- struct rtx_def *subtarget,
- enum machine_mode mode,
- int ignore));
+ 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. */