diff options
author | Jeff Law <law@gcc.gnu.org> | 1996-06-06 21:13:53 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1996-06-06 21:13:53 -0600 |
commit | fabe72bb8921275bb23c67d5c7b66f3fcc6d9721 (patch) | |
tree | e8784b33a47f72a014d0acd148b9c53511356145 | |
parent | c57a4b7c02ae67f4aa7cc5f636e7dd95d51e247a (diff) | |
download | gcc-fabe72bb8921275bb23c67d5c7b66f3fcc6d9721.zip gcc-fabe72bb8921275bb23c67d5c7b66f3fcc6d9721.tar.gz gcc-fabe72bb8921275bb23c67d5c7b66f3fcc6d9721.tar.bz2 |
h8300.c (h8300_monitor_function_p): New function.
* h8300/h8300.c (h8300_monitor_function_p): New function.
(h8300_os_task_function_p): Likewise.
(os_task, monitor): Variables to note if the current
function is an os_task or monitor.
(function_prologue): Set monitor and/or os_task as needed. Handle
os_task and monitor functions.
(function_epilogue): Clear monitor and os_task. Handle os_task and
monitor functions.
(h8300_valid_machine_decl_attribute): Accept "OS_Task" and
"monitor".
From-SVN: r12205
-rw-r--r-- | gcc/config/h8300/h8300.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index f086caf..6e6967c 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -42,6 +42,8 @@ void print_operand_address (); char *index (); static int h8300_interrupt_function_p PROTO ((tree)); +static int h8300_monitor_function_p PROTO ((tree)); +static int h8300_os_task_function_p PROTO ((tree)); /* CPU_TYPE, says what cpu we're compiling for. */ int cpu_type; @@ -50,6 +52,13 @@ int cpu_type; (either via #pragma or an attribute specification). */ int interrupt_handler; +/* True if the current fucntion is an OS Task + (via an attribute specification). */ +int os_task; + +/* True if the current function is a monitor + (via an attribute specification). */ +int monitor; /* True if a #pragma saveall has been seen for the current function. */ int pragma_saveall; @@ -206,6 +215,26 @@ function_prologue (file, size) if (h8300_interrupt_function_p (current_function_decl)) interrupt_handler = 1; + /* If the current function has the OS_Task attribute set, then + we have a naked prologue. */ + if (h8300_os_task_function_p (current_function_decl)) + { + fprintf (file, ";OS_Task prologue\n"); + os_task = 1; + return; + } + + if (h8300_monitor_function_p (current_function_decl)) + { + /* My understanding of monitor functions is they act just + like interrupt functions, except the prologue must + mask interrupts. */ + fprintf (file, ";monitor prologue\n"); + interrupt_handler = 1; + monitor = 1; + fprintf (file, "\torc\t#128,ccr\n"); + } + if (frame_pointer_needed) { /* Push fp */ @@ -255,6 +284,20 @@ function_epilogue (file, size) int idx; rtx insn = get_last_insn (); + if (os_task) + { + /* OS_Task epilogues are nearly naked -- they just have an + rts instruction. */ + fprintf (file, ";OS_task epilogue\n"); + fprintf (file, "\trts\n"); + goto out; + } + + /* monitor epilogues are the same as interrupt function epilogues. + Just make a note that we're in an monitor epilogue. */ + if (monitor) + fprintf(file, ";monitor epilogue\n"); + /* If the last insn was a BARRIER, we don't have to write any code. */ if (GET_CODE (insn) == NOTE) insn = prev_nonnote_insn (insn); @@ -295,7 +338,10 @@ function_epilogue (file, size) else fprintf (file, "\trts\n"); +out: interrupt_handler = 0; + os_task = 0; + monitor = 0; pragma_saveall = 0; } @@ -2185,6 +2231,38 @@ h8300_interrupt_function_p (func) return a != NULL_TREE; } +/* Return nonzero if FUNC is an OS_Task function as specified + by the "OS_Task" attribute. */ + +static int +h8300_os_task_function_p (func) + tree func; +{ + tree a; + + if (TREE_CODE (func) != FUNCTION_DECL) + return 0; + + a = lookup_attribute ("OS_Task", DECL_MACHINE_ATTRIBUTES (func)); + return a != NULL_TREE; +} + +/* Return nonzero if FUNC is a monitor function as specified + by the "monitor" attribute. */ + +static int +h8300_monitor_function_p (func) + tree func; +{ + tree a; + + if (TREE_CODE (func) != FUNCTION_DECL) + return 0; + + a = lookup_attribute ("monitor", DECL_MACHINE_ATTRIBUTES (func)); + return a != NULL_TREE; +} + /* Return nonzero if FUNC is a function that should be called through the function vector. */ @@ -2262,6 +2340,8 @@ h8300_valid_machine_decl_attribute (decl, attributes, attr, args) return 0; if (is_attribute_p ("interrupt_handler", attr) + || is_attribute_p ("OS_Task", attr) + || is_attribute_p ("monitor", attr) || is_attribute_p ("function_vector", attr)) return TREE_CODE (decl) == FUNCTION_DECL; |