*** avr.c.backup 2002-11-18 14:25:53.000000000 +0100 --- avr.c 2002-11-18 14:53:13.000000000 +0100 *************** *** 44,49 **** --- 44,50 ---- /* Maximal allowed offset for an address in the LD command */ #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE)) + static int task_s_function_p PARAMS ((tree)); static int avr_naked_function_p PARAMS ((tree)); static int interrupt_function_p PARAMS ((tree)); static int signal_function_p PARAMS ((tree)); *************** avr_reg_class_from_letter (c) *** 311,318 **** return NO_REGS; } ! /* Return non-zero if FUNC is a naked function. */ static int avr_naked_function_p (func) tree func; --- 312,331 ---- return NO_REGS; } ! /* Return non-zero if FUNC is a task function. */ ! static int ! task_s_function_p (func) ! tree func; ! { ! tree a; ! if (TREE_CODE (func) != FUNCTION_DECL) ! abort (); ! ! a = lookup_attribute ("task", DECL_ATTRIBUTES (func)); ! return a != NULL_TREE; ! } + /* Return non-zero if FUNC is a naked function. */ static int avr_naked_function_p (func) tree func; *************** avr_output_function_prologue (file, size *** 562,567 **** --- 575,581 ---- HOST_WIDE_INT size; { int reg; + int task_s_func_p; int interrupt_func_p; int signal_func_p; int leaf_func_p; *************** avr_output_function_prologue (file, size *** 588,593 **** --- 602,611 ---- prologue_size = 0; fprintf (file, "/* prologue: frame size=%d */\n", size); + task_s_func_p = task_s_function_p (current_function_decl); + if (task_s_function_p (current_function_decl)) + fputs ("/* prologue: TASK */\n", file); + if (interrupt_func_p) { fprintf (file,"\tsei\n"); *************** avr_output_function_prologue (file, size *** 644,650 **** { for (reg = 0; reg < 32; ++reg) { ! if ((!leaf_func_p && (call_used_regs[reg] && (interrupt_func_p || signal_func_p) && !(reg == TMP_REGNO || reg == ZERO_REGNO))) --- 662,668 ---- { for (reg = 0; reg < 32; ++reg) { ! if ( !task_s_func_p && ((!leaf_func_p && (call_used_regs[reg] && (interrupt_func_p || signal_func_p) && !(reg == TMP_REGNO || reg == ZERO_REGNO))) *************** avr_output_function_prologue (file, size *** 652,658 **** && (!call_used_regs[reg] || interrupt_func_p || signal_func_p) && ! (frame_pointer_needed ! && (reg == REG_Y || reg == (REG_Y+1))))) { fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]); ++prologue_size; --- 670,676 ---- && (!call_used_regs[reg] || interrupt_func_p || signal_func_p) && ! (frame_pointer_needed ! && (reg == REG_Y || reg == (REG_Y+1)))))) { fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]); ++prologue_size; *************** avr_output_function_prologue (file, size *** 661,672 **** if (frame_pointer_needed) { { 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; if (size) { fputs ("\t", file); --- 679,695 ---- if (frame_pointer_needed) { { + if (!task_s_func_p) + { + fprintf (file, "\t" + AS1 (push,r28) CR_TAB + AS1 (push,r29) "\n"); + prologue_size += 2; + } fprintf (file, "\t" AS2 (in,r28,__SP_L__) CR_TAB AS2 (in,r29,__SP_H__) "\n"); ! prologue_size += 2; if (size) { fputs ("\t", file); *************** avr_output_function_epilogue (file, size *** 713,718 **** --- 736,747 ---- return; } + if (task_s_function_p (current_function_decl)) + { + fputs ("/* epilogue: task */\n", file); + return; + } + interrupt_func_p = interrupt_function_p (current_function_decl); signal_func_p = signal_function_p (current_function_decl); leaf_func_p = leaf_function_p (); *************** class_likely_spilled_p (c) *** 4643,4648 **** --- 4672,4678 ---- prologue interrupts are disabled; interrupt - make a function to be hardware interrupt. After function prologue interrupts are enabled; + task - same as naked, but with stack frame setup at entry naked - don't generate function prologue/epilogue and `ret' command. Only `progmem' attribute valid for type. */ *************** const struct attribute_spec avr_attribut *** 4654,4659 **** --- 4684,4690 ---- { "signal", 0, 0, true, false, false, avr_handle_fndecl_attribute }, { "interrupt", 0, 0, true, false, false, avr_handle_fndecl_attribute }, { "naked", 0, 0, true, false, false, avr_handle_fndecl_attribute }, + { "task", 0, 0, true, false, false, avr_handle_fndecl_attribute }, { NULL, 0, 0, false, false, false, NULL } };