Commit bdfe906f by Richard Henderson Committed by Richard Henderson

avr.c (TARGET_EXCEPT_UNWIND_INFO): New.

	* config/avr/avr.c (TARGET_EXCEPT_UNWIND_INFO): New.
	(avr_incoming_return_addr_rtx): New.
	(emit_push_byte): New.
	(expand_prologue): Use it.  Remove incorrect dwarf annotation for
	SREG, RAMPZ, zero register.  Push frame pointer by bytes.  Add dwarf
	annotation for __prologue_saves__.  Fixup dwarf annotation for CFA.
	(emit_pop_byte): New.
	(expand_epilogue): Use it.  Pop frame pointer by bytes.
	* config/avr/avr.h (FRAME_POINTER_CFA_OFFSET): Remove.
	(INCOMING_RETURN_ADDR_RTX): New.
	(INCOMING_FRAME_SP_OFFSET): New.
	(ARG_POINTER_CFA_OFFSET): New.
	* config/avr/avr.md (*pushqi): Fix mode of auto-inc.
	(*pushhi, *pushsi, *pushsf, popqi): Likewise.
	(pophi): Remove.

From-SVN: r171295
parent 5b13621b
2011-03-22 Richard Henderson <rth@redhat.com>
* config/avr/avr.c (TARGET_EXCEPT_UNWIND_INFO): New.
(avr_incoming_return_addr_rtx): New.
(emit_push_byte): New.
(expand_prologue): Use it. Remove incorrect dwarf annotation for
SREG, RAMPZ, zero register. Push frame pointer by bytes. Add dwarf
annotation for __prologue_saves__. Fixup dwarf annotation for CFA.
(emit_pop_byte): New.
(expand_epilogue): Use it. Pop frame pointer by bytes.
* config/avr/avr.h (FRAME_POINTER_CFA_OFFSET): Remove.
(INCOMING_RETURN_ADDR_RTX): New.
(INCOMING_FRAME_SP_OFFSET): New.
(ARG_POINTER_CFA_OFFSET): New.
* config/avr/avr.md (*pushqi): Fix mode of auto-inc.
(*pushhi, *pushsi, *pushsf, popqi): Likewise.
(pophi): Remove.
2011-03-22 Nathan Froyd <froydnj@codesourcery.com> 2011-03-22 Nathan Froyd <froydnj@codesourcery.com>
* tree.c (build_call_1): New function. * tree.c (build_call_1): New function.
......
...@@ -108,6 +108,7 @@ extern RTX_CODE avr_normalize_condition (RTX_CODE condition); ...@@ -108,6 +108,7 @@ extern RTX_CODE avr_normalize_condition (RTX_CODE condition);
extern int compare_eq_p (rtx insn); extern int compare_eq_p (rtx insn);
extern void out_shift_with_cnt (const char *templ, rtx insn, extern void out_shift_with_cnt (const char *templ, rtx insn,
rtx operands[], int *len, int t_len); rtx operands[], int *len, int t_len);
extern rtx avr_incoming_return_addr_rtx (void);
#endif /* RTX_CODE */ #endif /* RTX_CODE */
#ifdef HAVE_MACHINE_MODES #ifdef HAVE_MACHINE_MODES
......
...@@ -246,6 +246,9 @@ static const struct default_options avr_option_optimization_table[] = ...@@ -246,6 +246,9 @@ static const struct default_options avr_option_optimization_table[] =
#undef TARGET_HELP #undef TARGET_HELP
#define TARGET_HELP avr_help #define TARGET_HELP avr_help
#undef TARGET_EXCEPT_UNWIND_INFO
#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
struct gcc_target targetm = TARGET_INITIALIZER; struct gcc_target targetm = TARGET_INITIALIZER;
static void static void
...@@ -597,6 +600,35 @@ get_sequence_length (rtx insns) ...@@ -597,6 +600,35 @@ get_sequence_length (rtx insns)
return length; return length;
} }
/* Implement INCOMING_RETURN_ADDR_RTX. */
rtx
avr_incoming_return_addr_rtx (void)
{
/* The return address is at the top of the stack. Note that the push
was via post-decrement, which means the actual address is off by one. */
return gen_frame_mem (HImode, plus_constant (stack_pointer_rtx, 1));
}
/* Helper for expand_prologue. Emit a push of a byte register. */
static void
emit_push_byte (unsigned regno, bool frame_related_p)
{
rtx mem, reg, insn;
mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
mem = gen_frame_mem (QImode, mem);
reg = gen_rtx_REG (QImode, regno);
insn = emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
if (frame_related_p)
RTX_FRAME_RELATED_P (insn) = 1;
cfun->machine->stack_usage++;
}
/* Output function prologue. */ /* Output function prologue. */
void void
...@@ -606,11 +638,6 @@ expand_prologue (void) ...@@ -606,11 +638,6 @@ expand_prologue (void)
HARD_REG_SET set; HARD_REG_SET set;
int minimize; int minimize;
HOST_WIDE_INT size = get_frame_size(); HOST_WIDE_INT size = get_frame_size();
/* Define templates for push instructions. */
rtx pushbyte = gen_rtx_MEM (QImode,
gen_rtx_POST_DEC (HImode, stack_pointer_rtx));
rtx pushword = gen_rtx_MEM (HImode,
gen_rtx_POST_DEC (HImode, stack_pointer_rtx));
rtx insn; rtx insn;
/* Init cfun->machine. */ /* Init cfun->machine. */
...@@ -638,46 +665,34 @@ expand_prologue (void) ...@@ -638,46 +665,34 @@ expand_prologue (void)
if (cfun->machine->is_interrupt || cfun->machine->is_signal) if (cfun->machine->is_interrupt || cfun->machine->is_signal)
{ {
/* Enable interrupts. */
if (cfun->machine->is_interrupt) if (cfun->machine->is_interrupt)
{ emit_insn (gen_enable_interrupt ());
/* Enable interrupts. */
insn = emit_insn (gen_enable_interrupt ());
RTX_FRAME_RELATED_P (insn) = 1;
}
/* Push zero reg. */ /* Push zero reg. */
insn = emit_move_insn (pushbyte, zero_reg_rtx); emit_push_byte (ZERO_REGNO, true);
RTX_FRAME_RELATED_P (insn) = 1;
cfun->machine->stack_usage++;
/* Push tmp reg. */ /* Push tmp reg. */
insn = emit_move_insn (pushbyte, tmp_reg_rtx); emit_push_byte (TMP_REGNO, true);
RTX_FRAME_RELATED_P (insn) = 1;
cfun->machine->stack_usage++;
/* Push SREG. */ /* Push SREG. */
insn = emit_move_insn (tmp_reg_rtx, /* ??? There's no dwarf2 column reserved for SREG. */
gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR))); emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)));
RTX_FRAME_RELATED_P (insn) = 1; emit_push_byte (TMP_REGNO, false);
insn = emit_move_insn (pushbyte, tmp_reg_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
cfun->machine->stack_usage++;
/* Push RAMPZ. */ /* Push RAMPZ. */
if(AVR_HAVE_RAMPZ /* ??? There's no dwarf2 column reserved for RAMPZ. */
&& (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1))) if (AVR_HAVE_RAMPZ
&& TEST_HARD_REG_BIT (set, REG_Z)
&& TEST_HARD_REG_BIT (set, REG_Z + 1))
{ {
insn = emit_move_insn (tmp_reg_rtx, emit_move_insn (tmp_reg_rtx,
gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR))); gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)));
RTX_FRAME_RELATED_P (insn) = 1; emit_push_byte (TMP_REGNO, false);
insn = emit_move_insn (pushbyte, tmp_reg_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
cfun->machine->stack_usage++;
} }
/* Clear zero reg. */ /* Clear zero reg. */
insn = emit_move_insn (zero_reg_rtx, const0_rtx); emit_move_insn (zero_reg_rtx, const0_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
/* Prevent any attempt to delete the setting of ZERO_REG! */ /* Prevent any attempt to delete the setting of ZERO_REG! */
emit_use (zero_reg_rtx); emit_use (zero_reg_rtx);
...@@ -686,37 +701,63 @@ expand_prologue (void) ...@@ -686,37 +701,63 @@ expand_prologue (void)
|| (AVR_2_BYTE_PC && live_seq > 6) || (AVR_2_BYTE_PC && live_seq > 6)
|| live_seq > 7)) || live_seq > 7))
{ {
insn = emit_move_insn (gen_rtx_REG (HImode, REG_X), int first_reg, reg, offset;
gen_int_mode (size, HImode));
RTX_FRAME_RELATED_P (insn) = 1; emit_move_insn (gen_rtx_REG (HImode, REG_X),
gen_int_mode (size, HImode));
insn = insn = emit_insn (gen_call_prologue_saves
emit_insn (gen_call_prologue_saves (gen_int_mode (live_seq, HImode), (gen_int_mode (live_seq, HImode),
gen_int_mode (size + live_seq, HImode))); gen_int_mode (size + live_seq, HImode)));
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
/* Describe the effect of the unspec_volatile call to prologue_saves.
Note that this formulation assumes that add_reg_note pushes the
notes to the front. Thus we build them in the reverse order of
how we want dwarf2out to process them. */
/* The function does always set frame_pointer_rtx, but whether that
is going to be permanent in the function is frame_pointer_needed. */
add_reg_note (insn, REG_CFA_ADJUST_CFA,
gen_rtx_SET (VOIDmode,
(frame_pointer_needed
? frame_pointer_rtx : stack_pointer_rtx),
plus_constant (stack_pointer_rtx,
-(size + live_seq))));
/* Note that live_seq always contains r28+r29, but the other
registers to be saved are all below 18. */
first_reg = 18 - (live_seq - 2);
for (reg = 29, offset = -live_seq + 1;
reg >= first_reg;
reg = (reg == 28 ? 17 : reg - 1), ++offset)
{
rtx m, r;
m = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, offset));
r = gen_rtx_REG (QImode, reg);
add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, m, r));
}
cfun->machine->stack_usage += size + live_seq; cfun->machine->stack_usage += size + live_seq;
} }
else else
{ {
int reg; int reg;
for (reg = 0; reg < 32; ++reg) for (reg = 0; reg < 32; ++reg)
{ if (TEST_HARD_REG_BIT (set, reg))
if (TEST_HARD_REG_BIT (set, reg)) emit_push_byte (reg, true);
{
/* Emit push of register to save. */
insn=emit_move_insn (pushbyte, gen_rtx_REG (QImode, reg));
RTX_FRAME_RELATED_P (insn) = 1;
cfun->machine->stack_usage++;
}
}
if (frame_pointer_needed) if (frame_pointer_needed)
{ {
if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)) if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
{ {
/* Push frame pointer. */ /* Push frame pointer. Always be consistent about the
insn = emit_move_insn (pushword, frame_pointer_rtx); ordering of pushes -- epilogue_restores expects the
RTX_FRAME_RELATED_P (insn) = 1; register pair to be pushed low byte first. */
cfun->machine->stack_usage += 2; emit_push_byte (REG_Y, true);
emit_push_byte (REG_Y + 1, true);
} }
if (!size) if (!size)
...@@ -739,13 +780,12 @@ expand_prologue (void) ...@@ -739,13 +780,12 @@ expand_prologue (void)
is selected. */ is selected. */
rtx myfp; rtx myfp;
rtx fp_plus_insns; rtx fp_plus_insns;
rtx sp_plus_insns = NULL_RTX;
if (AVR_HAVE_8BIT_SP) if (AVR_HAVE_8BIT_SP)
{ {
/* The high byte (r29) doesn't change - prefer 'subi' (1 cycle) /* The high byte (r29) doesn't change. Prefer 'subi'
over 'sbiw' (2 cycles, same size). */ (1 cycle) over 'sbiw' (2 cycles, same size). */
myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx)); myfp = gen_rtx_REG (QImode, FRAME_POINTER_REGNUM);
} }
else else
{ {
...@@ -756,41 +796,43 @@ expand_prologue (void) ...@@ -756,41 +796,43 @@ expand_prologue (void)
/* Method 1-Adjust frame pointer. */ /* Method 1-Adjust frame pointer. */
start_sequence (); start_sequence ();
insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx); /* Normally the dwarf2out frame-related-expr interpreter does
RTX_FRAME_RELATED_P (insn) = 1; not expect to have the CFA change once the frame pointer is
set up. Thus we avoid marking the move insn below and
instead indicate that the entire operation is complete after
the frame pointer subtraction is done. */
insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
emit_move_insn (myfp,
gen_rtx_PLUS (GET_MODE(myfp), myfp,
gen_int_mode (-size,
GET_MODE(myfp))));
RTX_FRAME_RELATED_P (insn) = 1;
/* Copy to stack pointer. */ insn = emit_move_insn (myfp, plus_constant (myfp, -size));
RTX_FRAME_RELATED_P (insn) = 1;
add_reg_note (insn, REG_CFA_ADJUST_CFA,
gen_rtx_SET (VOIDmode, frame_pointer_rtx,
plus_constant (stack_pointer_rtx,
-size)));
/* Copy to stack pointer. Note that since we've already
changed the CFA to the frame pointer this operation
need not be annotated at all. */
if (AVR_HAVE_8BIT_SP) if (AVR_HAVE_8BIT_SP)
{ {
insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
} }
else if (TARGET_NO_INTERRUPTS else if (TARGET_NO_INTERRUPTS
|| cfun->machine->is_signal || cfun->machine->is_signal
|| cfun->machine->is_OS_main) || cfun->machine->is_OS_main)
{ {
insn = emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx,
emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, frame_pointer_rtx));
frame_pointer_rtx));
RTX_FRAME_RELATED_P (insn) = 1;
} }
else if (cfun->machine->is_interrupt) else if (cfun->machine->is_interrupt)
{ {
insn = emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx,
frame_pointer_rtx)); frame_pointer_rtx));
RTX_FRAME_RELATED_P (insn) = 1;
} }
else else
{ {
insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx); emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
} }
fp_plus_insns = get_insns (); fp_plus_insns = get_insns ();
...@@ -799,30 +841,30 @@ expand_prologue (void) ...@@ -799,30 +841,30 @@ expand_prologue (void)
/* Method 2-Adjust Stack pointer. */ /* Method 2-Adjust Stack pointer. */
if (size <= 6) if (size <= 6)
{ {
rtx sp_plus_insns;
start_sequence (); start_sequence ();
insn = insn = plus_constant (stack_pointer_rtx, -size);
emit_move_insn (stack_pointer_rtx, insn = emit_move_insn (stack_pointer_rtx, insn);
gen_rtx_PLUS (HImode,
stack_pointer_rtx,
gen_int_mode (-size,
HImode)));
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
insn = insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
sp_plus_insns = get_insns (); sp_plus_insns = get_insns ();
end_sequence (); end_sequence ();
}
/* Use shortest method. */ /* Use shortest method. */
if (size <= 6 && (get_sequence_length (sp_plus_insns) if (get_sequence_length (sp_plus_insns)
< get_sequence_length (fp_plus_insns))) < get_sequence_length (fp_plus_insns))
emit_insn (sp_plus_insns); emit_insn (sp_plus_insns);
else else
emit_insn (fp_plus_insns);
}
else
emit_insn (fp_plus_insns); emit_insn (fp_plus_insns);
cfun->machine->stack_usage += size; cfun->machine->stack_usage += size;
} }
} }
...@@ -876,6 +918,20 @@ avr_epilogue_uses (int regno ATTRIBUTE_UNUSED) ...@@ -876,6 +918,20 @@ avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
return 0; return 0;
} }
/* Helper for expand_epilogue. Emit a pop of a byte register. */
static void
emit_pop_byte (unsigned regno)
{
rtx mem, reg;
mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
mem = gen_frame_mem (QImode, mem);
reg = gen_rtx_REG (QImode, regno);
emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
}
/* Output RTL epilogue. */ /* Output RTL epilogue. */
void void
...@@ -928,13 +984,12 @@ expand_epilogue (void) ...@@ -928,13 +984,12 @@ expand_epilogue (void)
/* Try two methods to adjust stack and select shortest. */ /* Try two methods to adjust stack and select shortest. */
rtx myfp; rtx myfp;
rtx fp_plus_insns; rtx fp_plus_insns;
rtx sp_plus_insns = NULL_RTX;
if (AVR_HAVE_8BIT_SP) if (AVR_HAVE_8BIT_SP)
{ {
/* The high byte (r29) doesn't change - prefer 'subi' /* The high byte (r29) doesn't change - prefer 'subi'
(1 cycle) over 'sbiw' (2 cycles, same size). */ (1 cycle) over 'sbiw' (2 cycles, same size). */
myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx)); myfp = gen_rtx_REG (QImode, FRAME_POINTER_REGNUM);
} }
else else
{ {
...@@ -945,10 +1000,7 @@ expand_epilogue (void) ...@@ -945,10 +1000,7 @@ expand_epilogue (void)
/* Method 1-Adjust frame pointer. */ /* Method 1-Adjust frame pointer. */
start_sequence (); start_sequence ();
emit_move_insn (myfp, emit_move_insn (myfp, plus_constant (myfp, size));
gen_rtx_PLUS (GET_MODE (myfp), myfp,
gen_int_mode (size,
GET_MODE(myfp))));
/* Copy to stack pointer. */ /* Copy to stack pointer. */
if (AVR_HAVE_8BIT_SP) if (AVR_HAVE_8BIT_SP)
...@@ -977,58 +1029,63 @@ expand_epilogue (void) ...@@ -977,58 +1029,63 @@ expand_epilogue (void)
/* Method 2-Adjust Stack pointer. */ /* Method 2-Adjust Stack pointer. */
if (size <= 5) if (size <= 5)
{ {
rtx sp_plus_insns;
start_sequence (); start_sequence ();
emit_move_insn (stack_pointer_rtx, emit_move_insn (stack_pointer_rtx,
gen_rtx_PLUS (HImode, stack_pointer_rtx, plus_constant (stack_pointer_rtx, size));
gen_int_mode (size,
HImode)));
sp_plus_insns = get_insns (); sp_plus_insns = get_insns ();
end_sequence (); end_sequence ();
}
/* Use shortest method. */ /* Use shortest method. */
if (size <= 5 && (get_sequence_length (sp_plus_insns) if (get_sequence_length (sp_plus_insns)
< get_sequence_length (fp_plus_insns))) < get_sequence_length (fp_plus_insns))
emit_insn (sp_plus_insns); emit_insn (sp_plus_insns);
else else
emit_insn (fp_plus_insns);
}
else
emit_insn (fp_plus_insns); emit_insn (fp_plus_insns);
} }
if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)) if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
{ {
/* Restore previous frame_pointer. */ /* Restore previous frame_pointer. See expand_prologue for
emit_insn (gen_pophi (frame_pointer_rtx)); rationale for not using pophi. */
emit_pop_byte (REG_Y + 1);
emit_pop_byte (REG_Y);
} }
} }
/* Restore used registers. */ /* Restore used registers. */
for (reg = 31; reg >= 0; --reg) for (reg = 31; reg >= 0; --reg)
{ if (TEST_HARD_REG_BIT (set, reg))
if (TEST_HARD_REG_BIT (set, reg)) emit_pop_byte (reg);
emit_insn (gen_popqi (gen_rtx_REG (QImode, reg)));
}
if (cfun->machine->is_interrupt || cfun->machine->is_signal) if (cfun->machine->is_interrupt || cfun->machine->is_signal)
{ {
/* Restore RAMPZ using tmp reg as scratch. */ /* Restore RAMPZ using tmp reg as scratch. */
if(AVR_HAVE_RAMPZ if (AVR_HAVE_RAMPZ
&& (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1))) && TEST_HARD_REG_BIT (set, REG_Z)
&& TEST_HARD_REG_BIT (set, REG_Z + 1))
{ {
emit_insn (gen_popqi (tmp_reg_rtx)); emit_pop_byte (TMP_REGNO);
emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(RAMPZ_ADDR)), emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)),
tmp_reg_rtx); tmp_reg_rtx);
} }
/* Restore SREG using tmp reg as scratch. */ /* Restore SREG using tmp reg as scratch. */
emit_insn (gen_popqi (tmp_reg_rtx)); emit_pop_byte (TMP_REGNO);
emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(SREG_ADDR)), emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)),
tmp_reg_rtx); tmp_reg_rtx);
/* Restore tmp REG. */ /* Restore tmp REG. */
emit_insn (gen_popqi (tmp_reg_rtx)); emit_pop_byte (TMP_REGNO);
/* Restore zero REG. */ /* Restore zero REG. */
emit_insn (gen_popqi (zero_reg_rtx)); emit_pop_byte (ZERO_REGNO);
} }
emit_jump_insn (gen_return ()); emit_jump_insn (gen_return ());
......
...@@ -351,9 +351,6 @@ enum reg_class { ...@@ -351,9 +351,6 @@ enum reg_class {
#define STATIC_CHAIN_REGNUM 2 #define STATIC_CHAIN_REGNUM 2
/* Offset from the frame pointer register value to the top of the stack. */
#define FRAME_POINTER_CFA_OFFSET(FNDECL) 0
#define ELIMINABLE_REGS { \ #define ELIMINABLE_REGS { \
{ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
...@@ -794,6 +791,13 @@ mmcu=*:-mmcu=%*}" ...@@ -794,6 +791,13 @@ mmcu=*:-mmcu=%*}"
#define OBJECT_FORMAT_ELF #define OBJECT_FORMAT_ELF
#define INCOMING_RETURN_ADDR_RTX avr_incoming_return_addr_rtx ()
#define INCOMING_FRAME_SP_OFFSET (AVR_3_BYTE_PC ? 3 : 2)
/* The caller's stack pointer value immediately before the call
is one byte below the first argument. */
#define ARG_POINTER_CFA_OFFSET(FNDECL) -1
#define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \ #define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
avr_hard_regno_rename_ok (OLD_REG, NEW_REG) avr_hard_regno_rename_ok (OLD_REG, NEW_REG)
......
...@@ -181,7 +181,7 @@ ...@@ -181,7 +181,7 @@
(define_insn "*pushqi" (define_insn "*pushqi"
[(set (mem:QI (post_dec (reg:HI REG_SP))) [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
(match_operand:QI 0 "reg_or_0_operand" "r,L"))] (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
"" ""
"@ "@
...@@ -189,9 +189,8 @@ ...@@ -189,9 +189,8 @@
push __zero_reg__" push __zero_reg__"
[(set_attr "length" "1,1")]) [(set_attr "length" "1,1")])
(define_insn "*pushhi" (define_insn "*pushhi"
[(set (mem:HI (post_dec (reg:HI REG_SP))) [(set (mem:HI (post_dec:HI (reg:HI REG_SP)))
(match_operand:HI 0 "reg_or_0_operand" "r,L"))] (match_operand:HI 0 "reg_or_0_operand" "r,L"))]
"" ""
"@ "@
...@@ -200,7 +199,7 @@ ...@@ -200,7 +199,7 @@
[(set_attr "length" "2,2")]) [(set_attr "length" "2,2")])
(define_insn "*pushsi" (define_insn "*pushsi"
[(set (mem:SI (post_dec (reg:HI REG_SP))) [(set (mem:SI (post_dec:HI (reg:HI REG_SP)))
(match_operand:SI 0 "reg_or_0_operand" "r,L"))] (match_operand:SI 0 "reg_or_0_operand" "r,L"))]
"" ""
"@ "@
...@@ -209,7 +208,7 @@ ...@@ -209,7 +208,7 @@
[(set_attr "length" "4,4")]) [(set_attr "length" "4,4")])
(define_insn "*pushsf" (define_insn "*pushsf"
[(set (mem:SF (post_dec (reg:HI REG_SP))) [(set (mem:SF (post_dec:HI (reg:HI REG_SP)))
(match_operand:SF 0 "register_operand" "r"))] (match_operand:SF 0 "register_operand" "r"))]
"" ""
"push %D0 "push %D0
...@@ -3126,20 +3125,12 @@ ...@@ -3126,20 +3125,12 @@
(define_insn "popqi" (define_insn "popqi"
[(set (match_operand:QI 0 "register_operand" "=r") [(set (match_operand:QI 0 "register_operand" "=r")
(mem:QI (post_inc (reg:HI REG_SP))))] (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
"" ""
"pop %0" "pop %0"
[(set_attr "cc" "none") [(set_attr "cc" "none")
(set_attr "length" "1")]) (set_attr "length" "1")])
(define_insn "pophi"
[(set (match_operand:HI 0 "register_operand" "=r")
(mem:HI (post_inc (reg:HI REG_SP))))]
""
"pop %A0\;pop %B0"
[(set_attr "cc" "none")
(set_attr "length" "2")])
;; Enable Interrupts ;; Enable Interrupts
(define_insn "enable_interrupt" (define_insn "enable_interrupt"
[(unspec [(const_int 0)] UNSPEC_SEI)] [(unspec [(const_int 0)] UNSPEC_SEI)]
......
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