[Bug target/14798] New: In case of SH target with -O2 option #pragma interrupt doesn't get resetted.
Jim Wilson
wilson@specifixinc.com
Thu Apr 29 06:32:00 GMT 2004
Anil Paranjape wrote:
> * sh/sh.c (sh_insert_attributes) : Flag pragma_interrupt is set to zero.
This patch has a number of problems.
It is only a partial fix. If pragma interrupt is broken, then the other similar
pragmas are all broken also. We shouldn't fix just one of them while leaving
the rest of them broken. Anything using a global variable in sh.c is suspect.
trap_exit, sp_switch, pragma_trapa, pragma_nosave_low_regs are all broken the
exact same way.
The reason why they are all broken is because they assume parsing, tree
generation, rtl generation, assembly generation all occur in order for one
function at a time. Note that the variables are cleared in
sh_output_function_epilogue, which occurs at the end of assembly generation.
This ordering is not true when -funit-at-a-time, which is now enabled by default
at -O2. This is also not true in the presence of nested functions, so this has
always been broken. It is just more obviously broken now.
current_function_interrupt is OK because it is set in expand_prologue and used
in expand_epilogue, and these will always occur in sequence, without an
intervening function.
current_function_anonymous_args is OK because it isn't used anywhere. It should
be deleted.
I think you are clearing pragma_interrupt in the wrong place in
sh_insert_attributes. I think it should be set only if an attribute is generated.
Since there are a number of places that use pragma_interrupt (the variable),
clearing it in sh_insert_attributes will break that code. Specifically, this
breaks the trapa and sp_switch attributes. This is trivial to show by adding an
attribute to your testcase like so.
void isr() __attribute__ ((trap_exit (4)))
{
}
This works (sort of) with current sources, but with your patch I get
tmp.c:3: warning: `trap_exit' attribute only applies to interrupt functions
tmp.c:3: error: parse error before '{' token
These problems can all be solved by getting rid of the global variables, and
using function calls to check for the presence of an attribute. See for
instance how the renesas attribute works.
Another alternative is to use variables in cfun, the current function context,
instead of global variables. Associating the variables with a function ensures
that they get saved/restored along with the rest of the function context. See
for example any target that defines a struct machine_function type, along with a
function to initialize it.
--
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com
More information about the Gcc-patches
mailing list