diff options
author | Jozef Lawrynowicz <jozef.l@mittosystems.com> | 2018-06-06 11:49:20 +0000 |
---|---|---|
committer | Jozef Lawrynowicz <jozefl@gcc.gnu.org> | 2018-06-06 11:49:20 +0000 |
commit | d71488c017b4ebb932cf2b4a43656e1eda670b23 (patch) | |
tree | 462308a806f1c8964920dce9f4e931c9209bdc9e /gcc | |
parent | 7db54ccd8a2b8a2c89f9cf38f716974aac27fa62 (diff) | |
download | gcc-d71488c017b4ebb932cf2b4a43656e1eda670b23.zip gcc-d71488c017b4ebb932cf2b4a43656e1eda670b23.tar.gz gcc-d71488c017b4ebb932cf2b4a43656e1eda670b23.tar.bz2 |
MSP430: Allow interrupt handlers to be static
* gcc/config/msp430/msp430.c (msp430_attr): Allow interrupt handlers
to be static and remove check on interrupt attribute name.
gcc/testsuite/gcc.target/msp430/
* function-attributes-4.c: New test.
* static-interrupts.c: New test.
From-SVN: r261229
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/msp430/msp430.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/msp430/function-attributes-4.c | 111 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/msp430/static-interrupts.c | 26 |
4 files changed, 153 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e7be008..85515d9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-06-06 Jozef Lawrynowicz <jozef.l@mittosystems.com> + + * gcc/config/msp430/msp430.c (msp430_attr): Allow interrupt handlers + to be static and remove check on interrupt attribute name. + + gcc/testsuite/gcc.target/msp430/ + * function-attributes-4.c: New test. + * static-interrupts.c: New test. + 2018-06-05 Kelvin Nilsen <kelvin@gcc.gnu.org> * doc/extend.texi (PowerPC AltiVec Built-in Functions): Remove diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index 8c8e676..9051761 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -1878,11 +1878,9 @@ msp430_attr (tree * node, { gcc_assert (DECL_P (* node)); + /* Only the interrupt attribute takes an argument. */ if (args != NULL) { - /* Only the interrupt attribute takes an argument. */ - gcc_assert (TREE_NAME_EQ (name, ATTR_INTR)); - tree value = TREE_VALUE (args); switch (TREE_CODE (value)) @@ -1927,13 +1925,12 @@ msp430_attr (tree * node, if (TREE_CODE (TREE_TYPE (* node)) == FUNCTION_TYPE && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node)))) message = "interrupt handlers must be void"; - - if (! TREE_PUBLIC (* node)) - message = "interrupt handlers cannot be static"; - - /* Ensure interrupt handlers never get optimised out. */ - TREE_USED (* node) = 1; - DECL_PRESERVE_P (* node) = 1; + else + { + /* Ensure interrupt handlers never get optimised out. */ + TREE_USED (* node) = 1; + DECL_PRESERVE_P (* node) = 1; + } } else if (TREE_NAME_EQ (name, ATTR_REENT)) { diff --git a/gcc/testsuite/gcc.target/msp430/function-attributes-4.c b/gcc/testsuite/gcc.target/msp430/function-attributes-4.c new file mode 100644 index 0000000..07d13c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/function-attributes-4.c @@ -0,0 +1,111 @@ +/* { dg-do compile } */ +/* Check that the foo interrupt vectors aren't actually removed. */ +/* { dg-final { scan-assembler-times "__interrupt_vector_foo" 2 } } */ + +/* Check that warnings are emitted when attributes are used incorrectly and + that attributes are interpreted correctly whether leading and trailing + underscores are used or not. */ + +void __attribute__((__naked__,__reentrant__)) +fn1(void) +{ /* { dg-warning "naked functions cannot be reentrant" } */ +} + +void __attribute__((naked,reentrant)) +fn2(void) +{ /* { dg-warning "naked functions cannot be reentrant" } */ +} + +void __attribute__((__reentrant__,__naked__)) +fn3(void) +{ /* { dg-warning "reentrant functions cannot be naked" } */ +} + +void __attribute__((reentrant,naked)) +fn4(void) +{ /* { dg-warning "reentrant functions cannot be naked" } */ +} + +void __attribute__((__critical__,__reentrant__)) +fn5(void) +{ /* { dg-warning "critical functions cannot be reentrant" } */ +} + +void __attribute__((critical,reentrant)) +fn6(void) +{ /* { dg-warning "critical functions cannot be reentrant" } */ +} + +void __attribute__((__reentrant__,__critical__)) +fn7(void) +{ /* { dg-warning "reentrant functions cannot be critical" } */ +} + +void __attribute__((reentrant,critical)) +fn8(void) +{ /* { dg-warning "reentrant functions cannot be critical" } */ +} + +void __attribute__((__critical__,__naked__)) +fn9(void) +{ /* { dg-warning "critical functions cannot be naked" } */ +} + +void __attribute__((critical,naked)) +fn10(void) +{ /* { dg-warning "critical functions cannot be naked" } */ +} + +void __attribute__((__naked__,__critical__)) +fn11(void) +{ /* { dg-warning "naked functions cannot be critical" } */ +} + +void __attribute__((naked,critical)) +fn12(void) +{ /* { dg-warning "naked functions cannot be critical" } */ +} + +int __attribute__((interrupt)) +isr1 (void) +{ /* { dg-warning "interrupt handlers must be void" } */ +} + +int __attribute__((__interrupt__)) +isr2 (void) +{ /* { dg-warning "interrupt handlers must be void" } */ +} + +void __attribute__((interrupt("foo1"))) +isr3 (void) +{ /* { dg-warning "unrecognized interrupt vector argument" } */ +} + +void __attribute__((__interrupt__("foo2"))) +isr4 (void) +{ /* { dg-warning "unrecognized.*interrupt vector argument" } */ +} + +void __attribute__((interrupt(65))) +isr5 (void) +{ /* { dg-warning "numeric argument of 'interrupt' attribute must be in range 0..63" } */ +} + +void __attribute__((__interrupt__(100))) +isr6 (void) +{ /* { dg-warning "numeric argument of 'interrupt' attribute must be in range 0..63" } */ +} + +void __attribute__((interrupt(0.5))) +isr7 (void) +{ /* { dg-warning "argument of 'interrupt' attribute is not a string constant or number" } */ + volatile int __attribute__((__naked__)) + a; /* { dg-warning "'naked' attribute only applies to functions" } */ +} + +void __attribute__((__interrupt__(1.5))) +isr8 (void) +{ /* { dg-warning "argument of 'interrupt' attribute is not a string constant or number" } */ + volatile int __attribute__((naked)) + a; /* { dg-warning "'naked' attribute only applies to functions" } */ +} diff --git a/gcc/testsuite/gcc.target/msp430/static-interrupts.c b/gcc/testsuite/gcc.target/msp430/static-interrupts.c new file mode 100644 index 0000000..06d9ea6 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/static-interrupts.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ +/* { dg-final { scan-assembler-times "__interrupt_vector_" 4 } } */ + +/* Test that interrupts aren't optimised out and that "__interrupt__" and + "interrupt" can be used interchangeably. */ + +static void __attribute__((interrupt(1))) +isr_static (void) +{ +} + +static void __attribute__((__interrupt__(2))) +isr_static_alt (void) +{ +} + +void __attribute__((interrupt(3))) +isr_global (void) +{ +} + +void __attribute__((__interrupt__(4))) +isr_global_alt (void) +{ +} |