freebsd-ports/devel/avr-gcc-42/files/patch-os_main-os_task
Joerg Wunsch 48c342e224 After upgrading devel/avr-gcc to GCC 4.3.x, keep a GCC 4.2.x version
here as it frequently produces more compact code (but supports less
target MCU types).
2009-06-17 19:33:59 +00:00

222 lines
6.6 KiB
Text

Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c (revision 129730)
+++ gcc/config/avr/avr.c (working copy)
@@ -48,6 +48,8 @@
#define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
static int avr_naked_function_p (tree);
+static int avr_OS_main_function_p (tree);
+static int avr_OS_task_function_p (tree);
static int interrupt_function_p (tree);
static int signal_function_p (tree);
static int avr_regs_to_save (HARD_REG_SET *);
@@ -400,6 +402,33 @@
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 nonzero if FUNC is a OS_task function. */
+
+static int
+avr_OS_task_function_p (tree func)
+{
+ tree a;
+
+ gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
+
+ a = lookup_attribute ("OS_task", TYPE_ATTRIBUTES (TREE_TYPE (func)));
+ return a != NULL_TREE;
+}
+
+
/* Return nonzero if FUNC is an interrupt function as specified
by the "interrupt" attribute. */
@@ -445,8 +474,11 @@
CLEAR_HARD_REG_SET (*set);
count = 0;
- /* No need to save any registers if the function never returns. */
- if (TREE_THIS_VOLATILE (current_function_decl))
+ /* No need to save any registers if the function never returns or
+ is have "OS_main" or OS_task attribute. */
+ if (TREE_THIS_VOLATILE (current_function_decl)
+ || avr_OS_main_function_p (current_function_decl)
+ || avr_OS_task_function_p (current_function_decl))
return 0;
for (reg = 0; reg < 32; reg++)
@@ -497,7 +529,6 @@
&& ! interrupt_function_p (current_function_decl)
&& ! signal_function_p (current_function_decl)
&& ! avr_naked_function_p (current_function_decl)
- && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
&& ! TREE_THIS_VOLATILE (current_function_decl));
}
@@ -666,7 +697,8 @@
int reg;
int interrupt_func_p;
int signal_func_p;
- int main_p;
+ int OS_main_p;
+ int OS_task_p;
int live_seq;
int minimize;
@@ -684,9 +716,11 @@
interrupt_func_p = interrupt_function_p (current_function_decl);
signal_func_p = signal_function_p (current_function_decl);
- main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
+ OS_main_p = avr_OS_main_function_p (current_function_decl);
+ OS_task_p = avr_OS_task_function_p (current_function_decl);
live_seq = sequent_regs_live ();
minimize = (TARGET_CALL_PROLOGUES
+ && !OS_main_p && !OS_task_p
&& !interrupt_func_p && !signal_func_p && live_seq);
if (interrupt_func_p)
@@ -704,19 +738,8 @@
AS1 (clr,__zero_reg__) "\n");
prologue_size += 5;
}
- if (main_p)
+ if (minimize && (frame_pointer_needed || live_seq > 6))
{
- fprintf (file, ("\t"
- AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
- AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
- AS2 (out,__SP_H__,r29) CR_TAB
- AS2 (out,__SP_L__,r28) "\n"),
- avr_init_stack, size, avr_init_stack, size);
-
- prologue_size += 4;
- }
- else if (minimize && (frame_pointer_needed || live_seq > 6))
- {
fprintf (file, ("\t"
AS1 (ldi, r26) ",lo8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
AS1 (ldi, r27) ",hi8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB), size, size);
@@ -754,12 +777,17 @@
}
if (frame_pointer_needed)
{
+ if (!OS_main_p && !OS_task_p)
+ {
+ fprintf (file, "\t"
+ AS1 (push,r28) CR_TAB
+ AS1 (push,r29) "\n");
+ prologue_size += 2;
+ }
fprintf (file, "\t"
- AS1 (push,r28) CR_TAB
- AS1 (push,r29) CR_TAB
AS2 (in,r28,__SP_L__) CR_TAB
AS2 (in,r29,__SP_H__) "\n");
- prologue_size += 4;
+ prologue_size += 2;
if (size)
{
fputs ("\t", file);
@@ -769,7 +797,7 @@
{
prologue_size += out_set_stack_ptr (file, 1, 1);
}
- else if (signal_func_p)
+ else if (signal_func_p || OS_main_p)
{
prologue_size += out_set_stack_ptr (file, 0, 0);
}
@@ -793,7 +821,8 @@
int reg;
int interrupt_func_p;
int signal_func_p;
- int main_p;
+ int OS_main_p;
+ int OS_task_p;
int function_size;
int live_seq;
int minimize;
@@ -825,28 +854,15 @@
interrupt_func_p = interrupt_function_p (current_function_decl);
signal_func_p = signal_function_p (current_function_decl);
- main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
+ OS_main_p = avr_OS_main_function_p (current_function_decl);
+ OS_task_p = avr_OS_task_function_p (current_function_decl);
live_seq = sequent_regs_live ();
minimize = (TARGET_CALL_PROLOGUES
+ && !OS_main_p && !OS_task_p
&& !interrupt_func_p && !signal_func_p && live_seq);
- if (main_p)
+ if (minimize && (frame_pointer_needed || live_seq > 4))
{
- /* Return value from main() is already in the correct registers
- (r25:r24) as the exit() argument. */
- if (AVR_MEGA)
- {
- fputs ("\t" AS1 (jmp,exit) "\n", file);
- epilogue_size += 2;
- }
- else
- {
- fputs ("\t" AS1 (rjmp,exit) "\n", file);
- ++epilogue_size;
- }
- }
- else if (minimize && (frame_pointer_needed || live_seq > 4))
- {
fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
++epilogue_size;
if (frame_pointer_needed)
@@ -893,10 +909,13 @@
epilogue_size += out_set_stack_ptr (file, -1, -1);
}
}
- fprintf (file, "\t"
- AS1 (pop,r29) CR_TAB
- AS1 (pop,r28) "\n");
- epilogue_size += 2;
+ if (!OS_main_p && !OS_task_p)
+ {
+ fprintf (file, "\t"
+ AS1 (pop,r29) CR_TAB
+ AS1 (pop,r28) "\n");
+ epilogue_size += 2;
+ }
}
epilogue_size += avr_regs_to_save (&set);
@@ -4643,6 +4662,8 @@
interrupt - make a function to be hardware interrupt. After function
prologue interrupts are enabled;
naked - don't generate function prologue/epilogue and `ret' command.
+ OS_main - ...
+ OS_task - ...
Only `progmem' attribute valid for type. */
@@ -4653,6 +4674,8 @@
{ "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute },
{ "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute },
{ "naked", 0, 0, false, true, true, avr_handle_fntype_attribute },
+ { "OS_main", 0, 0, false, true, true, avr_handle_fntype_attribute },
+ { "OS_task", 0, 0, false, true, true, avr_handle_fntype_attribute },
{ NULL, 0, 0, false, false, false, NULL }
};