48c342e224
here as it frequently produces more compact code (but supports less target MCU types).
222 lines
6.6 KiB
Text
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 }
|
|
};
|
|
|