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.
196 lines
7.1 KiB
Diff
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 }
|
|
};
|
|
|