summaryrefslogtreecommitdiff
path: root/devel/avr-gcc-42/files/patch-os_main-os_task
diff options
context:
space:
mode:
authorJoerg Wunsch <joerg@FreeBSD.org>2009-06-17 19:33:59 +0000
committerJoerg Wunsch <joerg@FreeBSD.org>2009-06-17 19:33:59 +0000
commit48c342e22472128049c9e278e4e6d3a578e0d477 (patch)
tree14caaf1cb3df899f71160f8432e023d6855334ec /devel/avr-gcc-42/files/patch-os_main-os_task
parent- Ensure Fortran shim is not built if USE_FORTRAN is not set. (diff)
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).
Notes
Notes: svn path=/head/; revision=236158
Diffstat (limited to 'devel/avr-gcc-42/files/patch-os_main-os_task')
-rw-r--r--devel/avr-gcc-42/files/patch-os_main-os_task222
1 files changed, 222 insertions, 0 deletions
diff --git a/devel/avr-gcc-42/files/patch-os_main-os_task b/devel/avr-gcc-42/files/patch-os_main-os_task
new file mode 100644
index 000000000000..3249e512a485
--- /dev/null
+++ b/devel/avr-gcc-42/files/patch-os_main-os_task
@@ -0,0 +1,222 @@
+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 }
+ };
+