Commit 97822902 by Anatoly Sokolov Committed by Anatoly Sokolov

avr.c (get_sequence_length): Add new function.

	* config/avr/avr.c (get_sequence_length): Add new function.
	(expand_prologue, expand_epilogue): Remove duplicate code.

From-SVN: r135775
parent 9f8e4e84
2008-05-22 Anatoly Sokolov <aesok@post.ru>
* config/avr/avr.c (get_sequence_length): Add new function.
(expand_prologue, expand_epilogue): Remove duplicate code.
2008-05-22 Rafael Espindola <espindola@google.com> 2008-05-22 Rafael Espindola <espindola@google.com>
* see.c (see_pre_insert_extensions): Use copy_rtx to avoid invalid rtx * see.c (see_pre_insert_extensions): Use copy_rtx to avoid invalid rtx
......
...@@ -54,6 +54,7 @@ static int signal_function_p (tree); ...@@ -54,6 +54,7 @@ static int signal_function_p (tree);
static int avr_OS_task_function_p (tree); static int avr_OS_task_function_p (tree);
static int avr_OS_main_function_p (tree); static int avr_OS_main_function_p (tree);
static int avr_regs_to_save (HARD_REG_SET *); static int avr_regs_to_save (HARD_REG_SET *);
static int get_sequence_length (rtx insns);
static int sequent_regs_live (void); static int sequent_regs_live (void);
static const char *ptrreg_to_str (int); static const char *ptrreg_to_str (int);
static const char *cond_string (enum rtx_code); static const char *cond_string (enum rtx_code);
...@@ -585,6 +586,20 @@ sequent_regs_live (void) ...@@ -585,6 +586,20 @@ sequent_regs_live (void)
return (cur_seq == live_seq) ? live_seq : 0; return (cur_seq == live_seq) ? live_seq : 0;
} }
/* Obtain the length sequence of insns. */
int
get_sequence_length (rtx insns)
{
rtx insn;
int length;
for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
length += get_attr_length (insn);
return length;
}
/* Output function prologue. */ /* Output function prologue. */
void void
...@@ -718,12 +733,11 @@ expand_prologue (void) ...@@ -718,12 +733,11 @@ expand_prologue (void)
To avoid a complex logic, both methods are tested and shortest To avoid a complex logic, both methods are tested and shortest
is selected. */ is selected. */
rtx myfp; rtx myfp;
/* First method. */ rtx fp_plus_insns;
rtx sp_plus_insns = NULL_RTX;
if (TARGET_TINY_STACK) if (TARGET_TINY_STACK)
{ {
if (size < -63 || size > 63)
warning (0, "large frame pointer change (%d) with -mtiny-stack", size);
/* The high byte (r29) doesn't change - prefer 'subi' (1 cycle) /* The high byte (r29) doesn't change - prefer 'subi' (1 cycle)
over 'sbiw' (2 cycles, same size). */ over 'sbiw' (2 cycles, same size). */
myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx)); myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
...@@ -733,51 +747,53 @@ expand_prologue (void) ...@@ -733,51 +747,53 @@ expand_prologue (void)
/* Normal sized addition. */ /* Normal sized addition. */
myfp = frame_pointer_rtx; myfp = frame_pointer_rtx;
} }
/* Calculate length. */
int method1_length; /* Method 1-Adjust frame pointer. */
method1_length = start_sequence ();
get_attr_length (gen_move_insn (frame_pointer_rtx, stack_pointer_rtx));
method1_length += insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
get_attr_length (gen_move_insn (myfp, RTX_FRAME_RELATED_P (insn) = 1;
gen_rtx_PLUS (GET_MODE(myfp), myfp,
gen_int_mode (-size, insn =
GET_MODE(myfp))))); emit_move_insn (myfp,
method1_length += gen_rtx_PLUS (GET_MODE(myfp), myfp,
get_attr_length (gen_move_insn (stack_pointer_rtx, frame_pointer_rtx)); gen_int_mode (-size,
GET_MODE(myfp))));
RTX_FRAME_RELATED_P (insn) = 1;
insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
fp_plus_insns = get_insns ();
end_sequence ();
/* Method 2-Adjust Stack pointer. */ /* Method 2-Adjust Stack pointer. */
int sp_plus_length = 0;
if (size <= 6) if (size <= 6)
{ {
sp_plus_length = start_sequence ();
get_attr_length (gen_move_insn (stack_pointer_rtx,
gen_rtx_PLUS (HImode, stack_pointer_rtx, insn =
gen_int_mode (-size, emit_move_insn (stack_pointer_rtx,
HImode)))); gen_rtx_PLUS (HImode,
sp_plus_length += stack_pointer_rtx,
get_attr_length (gen_move_insn (frame_pointer_rtx, stack_pointer_rtx)); gen_int_mode (-size,
HImode)));
RTX_FRAME_RELATED_P (insn) = 1;
insn =
emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
sp_plus_insns = get_insns ();
end_sequence ();
} }
/* Use shortest method. */ /* Use shortest method. */
if (size <= 6 && (sp_plus_length < method1_length)) if (size <= 6 && (get_sequence_length (sp_plus_insns)
{ < get_sequence_length (fp_plus_insns)))
insn = emit_move_insn (stack_pointer_rtx, emit_insn (sp_plus_insns);
gen_rtx_PLUS (HImode, stack_pointer_rtx,
gen_int_mode (-size, HImode)));
RTX_FRAME_RELATED_P (insn) = 1;
insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
}
else else
{ emit_insn (fp_plus_insns);
insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
insn = emit_move_insn (myfp,
gen_rtx_PLUS (GET_MODE(myfp), myfp,
gen_int_mode (-size, GET_MODE(myfp))));
RTX_FRAME_RELATED_P (insn) = 1;
insn = emit_move_insn ( stack_pointer_rtx, frame_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
}
} }
} }
} }
...@@ -872,42 +888,56 @@ expand_epilogue (void) ...@@ -872,42 +888,56 @@ expand_epilogue (void)
if (size) if (size)
{ {
/* Try two methods to adjust stack and select shortest. */ /* Try two methods to adjust stack and select shortest. */
int fp_plus_length; rtx myfp;
rtx fp_plus_insns;
rtx sp_plus_insns = NULL_RTX;
if (TARGET_TINY_STACK)
{
/* The high byte (r29) doesn't change - prefer 'subi'
(1 cycle) over 'sbiw' (2 cycles, same size). */
myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
}
else
{
/* Normal sized addition. */
myfp = frame_pointer_rtx;
}
/* Method 1-Adjust frame pointer. */ /* Method 1-Adjust frame pointer. */
fp_plus_length = start_sequence ();
get_attr_length (gen_move_insn (frame_pointer_rtx,
gen_rtx_PLUS (HImode, frame_pointer_rtx, emit_move_insn (myfp,
gen_int_mode (size, gen_rtx_PLUS (HImode, myfp,
HImode)))); gen_int_mode (size,
/* Copy to stack pointer. */ GET_MODE(myfp))));
fp_plus_length +=
get_attr_length (gen_move_insn (stack_pointer_rtx, frame_pointer_rtx)); /* Copy to stack pointer. */
emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
fp_plus_insns = get_insns ();
end_sequence ();
/* Method 2-Adjust Stack pointer. */ /* Method 2-Adjust Stack pointer. */
int sp_plus_length = 0;
if (size <= 5) if (size <= 5)
{ {
sp_plus_length = start_sequence ();
get_attr_length (gen_move_insn (stack_pointer_rtx,
gen_rtx_PLUS (HImode, stack_pointer_rtx, emit_move_insn (stack_pointer_rtx,
gen_int_mode (size, gen_rtx_PLUS (HImode, stack_pointer_rtx,
HImode)))); gen_int_mode (size,
HImode)));
sp_plus_insns = get_insns ();
end_sequence ();
} }
/* Use shortest method. */ /* Use shortest method. */
if (size <= 5 && (sp_plus_length < fp_plus_length)) if (size <= 5 && (get_sequence_length (sp_plus_insns)
{ < get_sequence_length (fp_plus_insns)))
emit_move_insn (stack_pointer_rtx, emit_insn (sp_plus_insns);
gen_rtx_PLUS (HImode, stack_pointer_rtx,
gen_int_mode (size, HImode)));
}
else else
{ emit_insn (fp_plus_insns);
emit_move_insn (frame_pointer_rtx,
gen_rtx_PLUS (HImode, frame_pointer_rtx,
gen_int_mode (size, HImode)));
/* Copy to stack pointer. */
emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
}
} }
if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)) if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment