Stefan Ernst schrob:
> Nicht nach der Dokumentation:
> These macros operate via automatic manipulation of the Global Interrupt
> Status (I) bit of the SREG register. Exit paths from both block types
> are all managed automatically without the need for special
> considerations, i. e. the interrupt status will be restored to the same
> value it has been when entering the respective block.
>
> Man beachte hier das
>> Exit paths from both block types are all managed automatically
>
> Wie das genau erreicht wird, habe ich mir aber noch nicht angeschaut.
Stimmt, wird recht geschickt über __attribute__((_cleanup_)) gemacht,
sehr interessant das. Kannte ich noch garnicht.
1 | static __inline__ uint8_t __iSeiRetVal(void)
|
2 | {
|
3 | __asm__ __volatile__ ("sei" ::);
|
4 | return 1;
|
5 | }
|
6 |
|
7 | static __inline__ uint8_t __iCliRetVal(void)
|
8 | {
|
9 | __asm__ __volatile__ ("cli" ::);
|
10 | return 1;
|
11 | }
|
12 |
|
13 | static __inline__ void __iSeiParam(const uint8_t *__s)
|
14 | {
|
15 | __asm__ __volatile__ ("sei" ::);
|
16 | __asm__ volatile ("" ::: "memory");
|
17 | (void)__s;
|
18 | }
|
19 |
|
20 | static __inline__ void __iCliParam(const uint8_t *__s)
|
21 | {
|
22 | __asm__ __volatile__ ("cli" ::);
|
23 | __asm__ volatile ("" ::: "memory");
|
24 | (void)__s;
|
25 | }
|
26 |
|
27 | static __inline__ void __iRestore(const uint8_t *__s)
|
28 | {
|
29 | (*(volatile uint8_t *)((0x3F) + 0x20)) = *__s;
|
30 | __asm__ volatile ("" ::: "memory");
|
31 | }
|
32 | # 2 "main.c" 2
|
33 |
|
34 | volatile int var;
|
35 |
|
36 | int test( void )
|
37 | {
|
38 | for ( uint8_t sreg_save __attribute__((__cleanup__(__iSeiParam))) = 0, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 ){
|
39 | return var;
|
40 | }
|
41 | }
|
Jedenfalls wird korrekter Code erzeugt, und IMHO kommt die Warnung hier
fälschlicher Weise, wenn es auch nichst einfach sein dürfte das im
Compiler zu fixen; dazu müsste die Warnung in einem späteres Pass kommen
als sie es jetzt tut.