#include "expr.h"
#include "function.h"
#include "optabs.h"
-#include "toplev.h"
+#include "diagnostic-core.h"
#include "c-family/c-pragma.h" /* ??? */
#include "tm_p.h"
#include "ggc.h"
#include "target.h"
#include "target-def.h"
+#include "df.h"
/* Classifies a h8300_src_operand or h8300_dst_operand.
H8_S
};
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
+
+static const struct default_options h8300_option_optimization_table[] =
+ {
+ /* Basic block reordering is only beneficial on targets with cache
+ and/or variable-cycle branches where (cycle count taken !=
+ cycle count not taken). */
+ { OPT_LEVELS_ALL, OPT_freorder_blocks, NULL, 0 },
+ { OPT_LEVELS_NONE, 0, NULL, 0 }
+ };
+
/* Initialize various cpu specific globals at start up. */
-void
-h8300_init_once (void)
+static void
+h8300_option_override (void)
{
static const char *const h8_push_ops[2] = { "push" , "push.l" };
static const char *const h8_pop_ops[2] = { "pop" , "pop.l" };
restore er6 though, so bump up the cost. */
h8300_move_ratio = 6;
}
+
+ /* This target defaults to strict volatile bitfields. */
+ if (flag_strict_volatile_bitfields < 0)
+ flag_strict_volatile_bitfields = 1;
}
/* Implement REG_CLASS_FROM_LETTER.
else
x = gen_push_h8300hs_normal (reg);
x = F (emit_insn (x), true);
- REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0);
+ add_reg_note (x, REG_INC, stack_pointer_rtx);
}
/* Emit an insn to pop register RN. */
else
x = gen_pop_h8300hs_normal (reg);
x = emit_insn (x);
- REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, 0);
+ add_reg_note (x, REG_INC, stack_pointer_rtx);
}
/* Emit an instruction to push or pop NREGS consecutive registers
/* If the next function argument with MODE and TYPE is to be passed in
a register, return a reg RTX for the hard register in which to pass
the argument. CUM represents the state after the last argument.
- If the argument is to be pushed, NULL_RTX is returned. */
+ If the argument is to be pushed, NULL_RTX is returned.
-rtx
-function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
- tree type, int named)
+ On the H8/300 all normal args are pushed, unless -mquickcall in which
+ case the first 3 arguments are passed in registers. */
+
+static rtx
+h8300_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ const_tree type, bool named)
{
static const char *const hand_list[] = {
"__main",
return result;
}
+
+/* Update the data in CUM to advance over an argument
+ of mode MODE and data type TYPE.
+ (TYPE is null for libcalls where that information may not be available.) */
+
+static void
+h8300_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ const_tree type, bool named ATTRIBUTE_UNUSED)
+{
+ cum->nbytes += (mode != BLKmode
+ ? (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD
+ : (int_size_in_bytes (type) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD);
+}
+
\f
/* Compute the cost of an and insn. */
return (to == STACK_POINTER_REGNUM ? ! frame_pointer_needed : true);
}
+/* Conditionally modify register usage based on target flags. */
+
+static void
+h8300_conditional_register_usage (void)
+{
+ if (!TARGET_MAC)
+ fixed_regs[MAC_REG] = call_used_regs[MAC_REG] = 1;
+}
+
/* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).
Define the offset between two registers, one to be eliminated, and
the other its replacement, at the start of a routine. */
/* Compute which flag bits are valid after an addition insn. */
-int
+enum attr_cc
compute_plussi_cc (rtx *operands)
{
enum machine_mode mode = GET_MODE (operands[0]);
/* Compute which flag bits are valid after a logical insn. */
-int
+enum attr_cc
compute_logical_op_cc (enum machine_mode mode, rtx *operands)
{
/* Figure out the logical op that we need to perform. */
/* Emit code to do shifts. */
bool
-expand_a_shift (enum machine_mode mode, int code, rtx operands[])
+expand_a_shift (enum machine_mode mode, enum rtx_code code, rtx operands[])
{
switch (h8sx_classify_shift (mode, code, operands[2]))
{
struct shift_insn
{
const char *const assembler;
- const int cc_valid;
+ const enum attr_cc cc_valid;
};
/* Assembler instruction shift table.
const char *shift2;
/* CC status for SHIFT_INLINE. */
- int cc_inline;
+ enum attr_cc cc_inline;
/* CC status for SHIFT_SPECIAL. */
- int cc_special;
+ enum attr_cc cc_special;
};
static void get_shift_alg (enum shift_type,
/* Compute which flag bits are valid after a shift insn. */
-int
+enum attr_cc
compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
{
rtx shift = operands[3];
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY h8300_return_in_memory
+#undef TARGET_FUNCTION_ARG
+#define TARGET_FUNCTION_ARG h8300_function_arg
+
+#undef TARGET_FUNCTION_ARG_ADVANCE
+#define TARGET_FUNCTION_ARG_ADVANCE h8300_function_arg_advance
+
#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG h8300_reorg
#undef TARGET_CAN_ELIMINATE
#define TARGET_CAN_ELIMINATE h8300_can_eliminate
+#undef TARGET_CONDITIONAL_REGISTER_USAGE
+#define TARGET_CONDITIONAL_REGISTER_USAGE h8300_conditional_register_usage
+
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT h8300_trampoline_init
+#undef TARGET_OPTION_OVERRIDE
+#define TARGET_OPTION_OVERRIDE h8300_option_override
+
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE h8300_option_optimization_table
+
+#undef TARGET_EXCEPT_UNWIND_INFO
+#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
+
struct gcc_target targetm = TARGET_INITIALIZER;