neingeist
/
arduinisten
Archived
1
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

196 lines
7.1 KiB
Diff

Not committed
Adds OS_main attribute feature.
Written by Anatoly Sokolov.
Apply patch after XMEGA patch.
--------------------------------------------------------------------------------
Index: gcc/function.c
===================================================================
--- gcc/function.c (revision 133747)
+++ gcc/function.c (working copy)
@@ -4756,6 +4756,14 @@
}
int
+prologue_contains (const_rtx insn)
+{
+ if (contains (insn, &prologue))
+ return 1;
+ return 0;
+}
+
+int
prologue_epilogue_contains (const_rtx insn)
{
if (contains (insn, &prologue))
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h (revision 133747)
+++ gcc/rtl.h (working copy)
@@ -2128,6 +2128,7 @@
/* In function.c */
extern void reposition_prologue_and_epilogue_notes (void);
+extern int prologue_contains (const_rtx);
extern int prologue_epilogue_contains (const_rtx);
extern int sibcall_epilogue_contains (const_rtx);
extern void mark_temp_addr_taken (rtx);
--- gcc/config/avr/avr.h.orig 2008-03-31 16:48:03.477537900 -0600
+++ gcc/config/avr/avr.h 2008-03-31 17:07:51.442457900 -0600
@@ -1095,4 +1095,8 @@ struct machine_function GTY(())
/* 'true' - if current function is a task function
as specified by the "OS_task" attribute. */
int is_OS_task;
+
+ /* 'true' - if current function is a 'main' function
+ as specified by the "OS_main" attribute. */
+ int is_OS_main;
};
--- gcc/config/avr/avr.c.orig Mon Mar 31 19:47:54 2008
+++ gcc/config/avr/avr.c Mon Mar 31 20:50:08 2008
@@ -53,6 +53,7 @@ static int interrupt_function_p (tree);
static int signal_function_p (tree);
static int nmi_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 void avr_args (HARD_REG_SET *);
static int sequent_regs_live (HARD_REG_SET *);
@@ -509,6 +513,19 @@ avr_OS_task_function_p (tree func)
return a != NULL_TREE;
}
+/* Return nonzero if FUNC is a OS_main function. */
+
+static int
+avr_OS_main_function_p (tree func)
+{
+ tree a;
+
+ gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
+
+ a = lookup_attribute ("OS_main", TYPE_ATTRIBUTES (TREE_TYPE (func)));
+ return a != NULL_TREE;
+}
+
/* Return the number of hard registers to push/pop in the prologue/epilogue
of the current function, and optionally store these registers in SET. */
@@ -527,9 +544,10 @@ avr_regs_to_save (HARD_REG_SET *set)
count = 0;
/* No need to save any registers if the function never returns or
- is have "OS_task" attribute. */
+ is have "OS_task" or "OS_main" attribute. */
if (TREE_THIS_VOLATILE (current_function_decl)
- || cfun->machine->is_OS_task)
+ || cfun->machine->is_OS_task
+ || cfun->machine->is_OS_main)
return 0;
for (reg = 0; reg < 32; reg++)
@@ -646,6 +664,8 @@ expand_prologue (void)
rtx pushword = gen_rtx_MEM (HImode,
gen_rtx_POST_DEC (HImode, stack_pointer_rtx));
rtx insn;
+ int method1_length;
+ int sp_plus_length;
last_insn_address = 0;
@@ -655,6 +675,7 @@ expand_prologue (void)
cfun->machine->is_signal = signal_function_p (current_function_decl);
cfun->machine->is_nmi = nmi_function_p (current_function_decl);
cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
+ cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
/* Prologue: naked. */
if (cfun->machine->is_naked)
@@ -669,6 +690,7 @@ expand_prologue (void)
&& !cfun->machine->is_interrupt
&& !cfun->machine->is_signal
&& !cfun->machine->is_OS_task
+ && !cfun->machine->is_OS_main
&& live_seq);
if (cfun->machine->is_interrupt || cfun->machine->is_signal)
@@ -738,7 +760,7 @@ expand_prologue (void)
}
if (frame_pointer_needed)
{
- if(!cfun->machine->is_OS_task)
+ if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
{
/* Push frame pointer. */
insn = emit_move_insn (pushword, frame_pointer_rtx);
@@ -768,7 +790,7 @@ expand_prologue (void)
if (TARGET_TINY_STACK)
{
if (size < -63 || size > 63)
- warning (0, "large frame pointer change (%d) with -mtiny-stack", size);
+ warning (0, "large frame pointer change (%ld) with -mtiny-stack", size);
/* The high byte (r29) doesn't change - prefer 'subi' (1 cycle)
over 'sbiw' (2 cycles, same size). */
@@ -780,7 +802,6 @@ expand_prologue (void)
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 +=
@@ -878,6 +899,7 @@ expand_epilogue (void)
HARD_REG_SET set;
int minimize;
HOST_WIDE_INT size = get_frame_size();
+ int sp_plus_length;
/* epilogue: naked */
if (cfun->machine->is_naked)
@@ -893,6 +915,7 @@ expand_epilogue (void)
&& !cfun->machine->is_interrupt
&& !cfun->machine->is_signal
&& !cfun->machine->is_OS_task
+ && !cfun->machine->is_OS_main
&& live_seq);
if (minimize && (frame_pointer_needed || live_seq > 4))
@@ -955,7 +978,7 @@ expand_epilogue (void)
emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
}
}
- if(!cfun->machine->is_OS_task)
+ if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
{
/* Restore previous frame_pointer. */
emit_insn (gen_pophi (frame_pointer_rtx));
@@ -1787,10 +1810,18 @@ output_movhi (rtx insn, rtx operands[],
}
/* Use simple load of stack pointer if no interrupts are used
or inside main or signal function prologue where they disabled. */
- else if (TARGET_NO_INTERRUPTS
+ else if ((!AVR_XMEGA && TARGET_NO_INTERRUPTS)
|| (!AVR_XMEGA
- && reload_completed
+ && reload_completed
&& cfun->machine->is_signal
+ && prologue_epilogue_contains (insn))
+ || (!AVR_XMEGA
+ && reload_completed
+ && cfun->machine->is_OS_main
+ && prologue_contains (insn))
+ || (AVR_XMEGA
+ && reload_completed
+ && cfun->machine->is_nmi
&& prologue_epilogue_contains (insn)))
{
*l = 2;
@@ -4821,6 +4852,7 @@ const struct attribute_spec avr_attribut
{ "nmi", 0, 0, true, false, false, avr_handle_fndecl_attribute },
{ "naked", 0, 0, false, true, true, avr_handle_fntype_attribute },
{ "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute },
+ { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute },
{ NULL, 0, 0, false, false, false, NULL }
};