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>
* see.c (see_pre_insert_extensions): Use copy_rtx to avoid invalid rtx
......
......@@ -54,6 +54,7 @@ static int signal_function_p (tree);
static int avr_OS_task_function_p (tree);
static int avr_OS_main_function_p (tree);
static int avr_regs_to_save (HARD_REG_SET *);
static int get_sequence_length (rtx insns);
static int sequent_regs_live (void);
static const char *ptrreg_to_str (int);
static const char *cond_string (enum rtx_code);
......@@ -585,6 +586,20 @@ sequent_regs_live (void)
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. */
void
......@@ -718,12 +733,11 @@ expand_prologue (void)
To avoid a complex logic, both methods are tested and shortest
is selected. */
rtx myfp;
/* First method. */
rtx fp_plus_insns;
rtx sp_plus_insns = NULL_RTX;
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)
over 'sbiw' (2 cycles, same size). */
myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
......@@ -733,51 +747,53 @@ expand_prologue (void)
/* Normal sized addition. */
myfp = frame_pointer_rtx;
}
/* Calculate length. */
int method1_length;
method1_length =
get_attr_length (gen_move_insn (frame_pointer_rtx, stack_pointer_rtx));
method1_length +=
get_attr_length (gen_move_insn (myfp,
gen_rtx_PLUS (GET_MODE(myfp), myfp,
gen_int_mode (-size,
GET_MODE(myfp)))));
method1_length +=
get_attr_length (gen_move_insn (stack_pointer_rtx, frame_pointer_rtx));
/* Method 1-Adjust frame pointer. */
start_sequence ();
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;
fp_plus_insns = get_insns ();
end_sequence ();
/* Method 2-Adjust Stack pointer. */
int sp_plus_length = 0;
if (size <= 6)
{
sp_plus_length =
get_attr_length (gen_move_insn (stack_pointer_rtx,
gen_rtx_PLUS (HImode, stack_pointer_rtx,
gen_int_mode (-size,
HImode))));
sp_plus_length +=
get_attr_length (gen_move_insn (frame_pointer_rtx, stack_pointer_rtx));
start_sequence ();
insn =
emit_move_insn (stack_pointer_rtx,
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;
sp_plus_insns = get_insns ();
end_sequence ();
}
/* Use shortest method. */
if (size <= 6 && (sp_plus_length < method1_length))
{
insn = emit_move_insn (stack_pointer_rtx,
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;
}
if (size <= 6 && (get_sequence_length (sp_plus_insns)
< get_sequence_length (fp_plus_insns)))
emit_insn (sp_plus_insns);
else
{
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;
}
emit_insn (fp_plus_insns);
}
}
}
......@@ -872,42 +888,56 @@ expand_epilogue (void)
if (size)
{
/* 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. */
fp_plus_length =
get_attr_length (gen_move_insn (frame_pointer_rtx,
gen_rtx_PLUS (HImode, frame_pointer_rtx,
gen_int_mode (size,
HImode))));
/* Copy to stack pointer. */
fp_plus_length +=
get_attr_length (gen_move_insn (stack_pointer_rtx, frame_pointer_rtx));
start_sequence ();
emit_move_insn (myfp,
gen_rtx_PLUS (HImode, myfp,
gen_int_mode (size,
GET_MODE(myfp))));
/* 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. */
int sp_plus_length = 0;
if (size <= 5)
{
sp_plus_length =
get_attr_length (gen_move_insn (stack_pointer_rtx,
gen_rtx_PLUS (HImode, stack_pointer_rtx,
gen_int_mode (size,
HImode))));
start_sequence ();
emit_move_insn (stack_pointer_rtx,
gen_rtx_PLUS (HImode, stack_pointer_rtx,
gen_int_mode (size,
HImode)));
sp_plus_insns = get_insns ();
end_sequence ();
}
/* Use shortest method. */
if (size <= 5 && (sp_plus_length < fp_plus_length))
{
emit_move_insn (stack_pointer_rtx,
gen_rtx_PLUS (HImode, stack_pointer_rtx,
gen_int_mode (size, HImode)));
}
if (size <= 5 && (get_sequence_length (sp_plus_insns)
< get_sequence_length (fp_plus_insns)))
emit_insn (sp_plus_insns);
else
{
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);
}
emit_insn (fp_plus_insns);
}
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