int picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum,
enum machine_mode mode,
tree type, bool named);
+rtx picochip_function_arg (CUMULATIVE_ARGS * p_cum,
+ enum machine_mode mode,
+ const_tree type, bool named);
+rtx picochip_incoming_function_arg (CUMULATIVE_ARGS * p_cum,
+ enum machine_mode mode,
+ const_tree type, bool named);
+void picochip_arg_advance (CUMULATIVE_ARGS * p_cum, enum machine_mode mode,
+ const_tree type, bool named);
int picochip_sched_lookahead (void);
int picochip_sched_issue_rate (void);
static rtx picochip_static_chain (const_tree, bool);
+static void picochip_option_override (void);
+
/* Lookup table mapping a register number to the earliest containing
class. Used by REGNO_REG_CLASS. */
const enum reg_class picochip_regno_reg_class[FIRST_PSEUDO_REGISTER] =
/* Determine which ALU to use for the instruction in
picochip_current_prescan_insn. */
static char picochip_get_vliw_alu_id (void);
+
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
+static const struct default_options picochip_option_optimization_table[] =
+ {
+ { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+ { OPT_LEVELS_NONE, 0, NULL, 0 }
+ };
\f
/* Initialize the GCC target structure. */
#undef TARGET_ARG_PARTIAL_BYTES
#define TARGET_ARG_PARTIAL_BYTES picochip_arg_partial_bytes
+#undef TARGET_FUNCTION_ARG
+#define TARGET_FUNCTION_ARG picochip_function_arg
+
+#undef TARGET_FUNCTION_INCOMING_ARG
+#define TARGET_FUNCTION_INCOMING_ARG picochip_incoming_function_arg
+
+#undef TARGET_FUNCTION_ARG_ADVANCE
+#define TARGET_FUNCTION_ARG_ADVANCE picochip_arg_advance
+
#undef TARGET_PROMOTE_FUNCTION_MODE
#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
#undef TARGET_PROMOTE_PROTOTYPES
#undef TARGET_STATIC_CHAIN
#define TARGET_STATIC_CHAIN picochip_static_chain
+#undef TARGET_OPTION_OVERRIDE
+#define TARGET_OPTION_OVERRIDE picochip_option_override
+
#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
-#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE picochip_override_options
+#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE picochip_option_override
+
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE picochip_option_optimization_table
+
+#undef TARGET_EXCEPT_UNWIND_INFO
+#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
struct gcc_target targetm = TARGET_INITIALIZER;
\f
return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 4);
}
-/* Allow certain command options to be overriden. */
-void
-picochip_override_options (void)
+/* Allow some options to be overriden. In particular, the 2nd
+ scheduling pass option is switched off, and a machine dependent
+ reorganisation ensures that it is run later on, after the second
+ jump optimisation. */
+
+static void
+picochip_option_override (void)
{
/* If we are optimizing for stack, dont let inliner to inline functions
that could potentially increase stack size.*/
if (flag_conserve_stack)
- {
- PARAM_VALUE (PARAM_LARGE_STACK_FRAME) = 0;
- PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) = 0;
- }
+ {
+ maybe_set_param_value (PARAM_LARGE_STACK_FRAME, 0,
+ global_options.x_param_values,
+ global_options_set.x_param_values);
+ maybe_set_param_value (PARAM_STACK_FRAME_GROWTH, 0,
+ global_options.x_param_values,
+ global_options_set.x_param_values);
+ }
/* Turn off the elimination of unused types. The elaborator
generates various interesting types to represent constants,
so that the correct Dwarf information is generated (see documention
for RTX_FRAME_RELATED_P for more details). */
RTX_FRAME_RELATED_P (insn) = 1;
- REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
- gen_rtx_SET (VOIDmode, stack_pointer_reg,
- gen_rtx_PLUS (Pmode, stack_pointer_reg,
- GEN_INT (-adjustment))),
- REG_NOTES (insn));
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR,
+ gen_rtx_SET (VOIDmode, stack_pointer_reg,
+ gen_rtx_PLUS (Pmode, stack_pointer_reg,
+ GEN_INT (-adjustment))));
}
gen_rtx_REG (HImode, REGNO (reg) + 1));
RTX_FRAME_RELATED_P (RTVEC_ELT (p, 1)) = 1;
- REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
- gen_rtx_PARALLEL (VOIDmode, p),
- REG_NOTES (insn));
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR,
+ gen_rtx_PARALLEL (VOIDmode, p));
}
break;
static void
picochip_emit_restore_register (rtx reg, int offset)
{
- rtx stack_pointer, address, mem, insn;
+ rtx stack_pointer, address, mem;
stack_pointer = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
mem = gen_rtx_MEM (GET_MODE (reg), address);
- insn = emit_move_insn (reg, mem);
+ emit_move_insn (reg, mem);
}
/* Compute the size of an argument in units. */
static int
-picochip_compute_arg_size (tree type, enum machine_mode mode)
+picochip_compute_arg_size (const_tree type, enum machine_mode mode)
{
int type_size_in_units = 0;
/* Determine where the next outgoing arg should be placed. */
rtx
-picochip_function_arg (CUMULATIVE_ARGS cum, int mode, tree type,
- int named ATTRIBUTE_UNUSED)
+picochip_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ const_tree type, bool named ATTRIBUTE_UNUSED)
{
int reg = 0;
int type_align_in_units = 0;
/* Compute the correct offset (i.e., ensure that the offset meets
the alignment requirements). */
- offset_overflow = cum % type_align_in_units;
+ offset_overflow = *cum % type_align_in_units;
if (offset_overflow == 0)
- new_offset = cum;
+ new_offset = *cum;
else
- new_offset = (cum - offset_overflow) + type_align_in_units;
+ new_offset = (*cum - offset_overflow) + type_align_in_units;
if (TARGET_DEBUG)
{
printf ("Function arg:\n");
printf (" Type valid: %s\n", (type ? "yes" : "no"));
- printf (" Cumulative Value: %d\n", cum);
+ printf (" Cumulative Value: %d\n", *cum);
printf (" Mode: %s\n", GET_MODE_NAME (mode));
printf (" Type size: %i units\n", type_size_in_units);
printf (" Alignment: %i units\n", type_align_in_units);
case CSImode:
case SCmode:
case CQImode:
- return gen_rtx_REG ((enum machine_mode) mode, reg);
+ return gen_rtx_REG (mode, reg);
case BLKmode:
{
passed in registers, which are then pushed onto the stack by the
function prologue). */
rtx
-picochip_incoming_function_arg (CUMULATIVE_ARGS cum, int mode,
- tree type, int named)
+picochip_incoming_function_arg (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode,
+ const_tree type, bool named)
{
if (cfun->stdarg)
}
-/* Advance the cumulative args counter, returning the new counter. */
-CUMULATIVE_ARGS
-picochip_arg_advance (const CUMULATIVE_ARGS cum, int mode,
- tree type, int named ATTRIBUTE_UNUSED)
+/* Advance the cumulative args counter CUM. */
+void
+picochip_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ const_tree type, bool named ATTRIBUTE_UNUSED)
{
int type_align_in_units = 0;
int type_size_in_units;
/* VOIDmode is passed when computing the second argument to a `call'
pattern. This can be ignored. */
if (mode == VOIDmode)
- return 0;
+ return;
/* Compute the alignment and size of the parameter. */
type_align_in_units =
/* Compute the correct offset (i.e., ensure that the offset meets
the alignment requirements). */
- offset_overflow = cum % type_align_in_units;
+ offset_overflow = *cum % type_align_in_units;
if (offset_overflow == 0)
- new_offset = cum;
+ new_offset = *cum;
else
- new_offset = (cum - offset_overflow) + type_align_in_units;
+ new_offset = (*cum - offset_overflow) + type_align_in_units;
/* Advance past the last argument. */
new_offset += type_size_in_units;
- return new_offset;
-
+ *cum = new_offset;
}
/* Determine whether a register needs saving/restoring. It does if it
{
int high_val, low_val, offset;
offset = INTVAL (XEXP (x, 1));
- // Ignore cases with negative offsets.
+ /* Ignore cases with negative offsets. */
if (offset < 0)
return x;
high_val = offset & mask_val;
return 1;
}
- // Depending on mode, the offsets allowed are either 16/32/64.
+ /* Depending on mode, the offsets allowed are either 16/32/64. */
switch (mode)
{
case QImode:
{
int high_val, low_val, offset;
offset = INTVAL (XEXP (*x, 1));
- // Ignore cases with negative offsets.
+ /* Ignore cases with negative offsets. */
if (offset < 0)
return 0;
high_val = offset & mask_val;
sprintf (picochip_current_vliw_state.lm_label_name,
"picoMark_%s%ld", prefix, num);
}
+ else if (picochip_schedule_type == DFA_TYPE_SPEED &&
+ (strcmp (prefix, "LCFI")) == 0 && picochip_vliw_continuation)
+ {
+ if (picochip_current_vliw_state.num_cfi_labels_deferred == 2)
+ {
+ internal_error ("LCFI labels have already been deferred.");
+ }
+ sprintf(picochip_current_vliw_state.cfi_label_name[
+ picochip_current_vliw_state.num_cfi_labels_deferred],
+ "picoMark_%s%ld", prefix, num);
+ picochip_current_vliw_state.num_cfi_labels_deferred++;
+ }
else
{
/* Marker label. */
/* Variable tracking should be run after all optimizations which change order
of insns. It also needs a valid CFG. This can't be done in
- picochip_override_options, because flag_var_tracking is finalized after
+ picochip_option_override, because flag_var_tracking is finalized after
that. */
picochip_flag_var_tracking = flag_var_tracking;
flag_var_tracking = 0;
int isRealShortBranch = (get_attr_length(insn) == SHORT_BRANCH_LENGTH);
return (isRealShortBranch ||
- (!isRealShortBranch &&
- picochip_current_vliw_state.num_insns_in_packet > 1));
+ picochip_current_vliw_state.num_insns_in_packet > 1);
}
/* Output a compare-and-branch instruction (matching the cbranch
FOR_EACH_BB (bb)
{
rtx insn, next, last_insn = NULL_RTX;
- rtx vliw_start = NULL_RTX;
rtx queue = NULL_RTX;
/* Iterate through the bb and find the last non-debug insn */
for (insn = get_insns (); insn; insn = next_insn (insn))
{
/* The prologue end must be moved to the end of the VLIW packet. */
- if (NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END)
+ if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END)
{
prologue_end_note = insn;
break;
if (last_insn_in_packet != NULL)
{
- rtx tmp_note = emit_note_after (NOTE_KIND(prologue_end_note), last_insn_in_packet);
+ rtx tmp_note
+ = emit_note_after ((enum insn_note) NOTE_KIND (prologue_end_note),
+ last_insn_in_packet);
memcpy(&NOTE_DATA (tmp_note), &NOTE_DATA(prologue_end_note), sizeof(NOTE_DATA(prologue_end_note)));
delete_insn (prologue_end_note);
}
/* Grab the incoming argument and emit its RTL. */
arg0 = CALL_EXPR_ARG (call, 0);
- op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
/* Determine the modes of the instruction operands. */
tmode = insn_data[icode].operand[0].mode;
arg1 = CALL_EXPR_ARG (call, 1);
/* Emit rtl sequences for the function arguments. */
- op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
- op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
/* Get the mode's of each of the instruction operands. */
tmode = insn_data[icode].operand[0].mode;
arg1 = CALL_EXPR_ARG (call, 1);
/* Emit rtl sequences for the function arguments. */
- op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
- op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
/* Get the mode's of each of the instruction operands. */
mode0 = insn_data[icode].operand[0].mode;
arg2 = CALL_EXPR_ARG (call, 2) ;
/* Emit rtl sequences for the function arguments. */
- op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
- op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
- op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ op2 = expand_expr (arg2, NULL_RTX, VOIDmode, EXPAND_NORMAL);
/* The second and third operands must be constant. Nothing else will
do. */
arg3 = CALL_EXPR_ARG (call, 3);
/* Emit rtl sequences for the function arguments. */
- op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
- op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
- op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
- op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ op2 = expand_expr (arg2, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ op3 = expand_expr (arg3, NULL_RTX, VOIDmode, EXPAND_NORMAL);
/* The first operand must be an SImode register. */
if (GET_MODE (op0) != SImode || REG != GET_CODE (op0))
arg2 = CALL_EXPR_ARG (call, 2);
/* Emit rtl sequences for the function arguments. */
- op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
- op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
- op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ op2 = expand_expr (arg2, NULL_RTX, VOIDmode, EXPAND_NORMAL);
/* The first operand must be a HImode register, or a constant. If it
isn't, force it into a HImode register. */
tree_cons (NULL_TREE, integer_type_node, int_int_endlink);
tree int_long_endlink =
tree_cons (NULL_TREE, integer_type_node, long_endlink);
- tree pchar_type_node = build_pointer_type (char_type_node);
tree long_int_int_int_endlink =
tree_cons (NULL_TREE, long_integer_type_node, int_int_int_endlink);
- tree int_ftype_void, int_ftype_int, int_ftype_int_int, void_ftype_pchar;
- tree long_ftype_int, long_ftype_int_int, long_ftype_int_int_int;
+ tree int_ftype_int, int_ftype_int_int;
+ tree long_ftype_int, long_ftype_int_int_int;
tree void_ftype_int_long, int_ftype_int_int_int,
void_ftype_long_int_int_int;
- tree void_ftype_void, void_ftype_int, unsigned_ftype_unsigned;
+ tree void_ftype_void, unsigned_ftype_unsigned;
/* void func (void) */
void_ftype_void = build_function_type (void_type_node, endlink);
- /* void func (void *) */
- void_ftype_pchar
- = build_function_type (void_type_node,
- tree_cons (NULL_TREE, pchar_type_node, endlink));
-
- /* int func (void) */
- int_ftype_void = build_function_type (integer_type_node, endlink);
-
- /* void func (int) */
- void_ftype_int = build_function_type (void_type_node, int_endlink);
-
/* int func (int) */
int_ftype_int = build_function_type (integer_type_node, int_endlink);
/* long func(int) */
long_ftype_int = build_function_type (long_integer_type_node, int_endlink);
- /* long func(int, int) */
- long_ftype_int_int
- = build_function_type (long_integer_type_node, int_int_endlink);
-
/* long func(int, int, int) */
long_ftype_int_int_int
= build_function_type (long_integer_type_node, int_int_int_endlink);