With msp430-gcc V3.2.3 I seem to get incorrect code when using the saveprologue attribute function on an interrupt function (maybe this is not intended to work this way)

Here is my test code,

/*
 * msp saveprologue test routine
 */

#include <io.h>
#include <signal.h>

volatile int a;

main()
{
    int x;

    for (;;)
    {
        x = x + a;
        a = 0;
    }
}

interrupt (TIMERA1_VECTOR) timerA1Int(void)
{
    a = 1;
}

interrupt (TIMERA0_VECTOR) saveprologue timerA0Int(void)
{
    a = 2;
}

The compile line and compile output

[peter_...@sts-cvs test]$ msp430-gcc -v -mmcu=msp430x149 -o test test.c
Reading specs from /usr/local/lib/gcc-lib/msp430/3.2.3/specs
Configured with: ../gcc-3.2.3/configure --target=msp430
Thread model: single
gcc version 3.2.3
/usr/local/lib/gcc-lib/msp430/3.2.3/cc1 -lang-c -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=3 -D__GXX_ABI_VERSION=102 -DMSP430 -D__MSP430__ -D__MSP430 -D__NO_INLINE__ -D__STDC_HOSTED__=1 -DMSP430_HAS_HW_MUL -D__MSP430_149__ -DMSP430_HAS_HWMUL -D__SIZE_TYPE__=unsigned int -D__PTRDIFF_TYPE__=int -D__INT_MAX__=32767 test.c -quiet -dumpbase test.c -mmcu=msp430x149 -version -o /tmp/ccbZOnZg.s
GNU CPP version 3.2.3 (cpplib) (GNU assembler syntax)
GNU C version 3.2.3 (msp430)
        compiled by GNU C version 3.2 20020903 (Red Hat Linux 8.0 3.2-7).
ignoring nonexistent directory "NONE/include"
ignoring nonexistent directory "/usr/local/msp430/sys-include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/lib/gcc-lib/msp430/3.2.3/include
 /usr/local/msp430/include
End of search list.
/usr/local/lib/gcc-lib/msp430/3.2.3/../../../../msp430/bin/as -o /tmp/cc4BB3Rr.o /tmp/ccbZOnZg.s msp430-ld -m msp430x149 -o test /usr/local/lib/gcc-lib/msp430/3.2.3/../../../../msp430/lib/crt430x149.o -L/usr/local/lib/gcc-lib/msp430/3.2.3/msp2 -L/usr/local/lib/gcc-lib/msp430/3.2.3 -L/usr/local/lib/gcc-lib/msp430/3.2.3/../../../../msp430/lib/msp2 -L/usr/local/lib/gcc-lib/msp430/3.2.3/../../../../msp430/lib /tmp/cc4BB3Rr.o -lgcc -lc -lgcc

and the generated code
[peter_...@sts-cvs test]$ msp430-objdump -dS test

test:     file format elf32-msp430

Disassembly of section .text:

00001100 <_reset_vector__>:
    1100:       b2 40 80 5a     mov     #23168, &0x0120 ;#0x5a80
    1104:       20 01
    1106:       3f 40 90 11     mov     #4496,  r15     ;#0x1190
    110a:       3e 40 00 02     mov     #512,   r14     ;#0x0200
    110e:       3d 40 00 02     mov     #512,   r13     ;#0x0200
    1112:       0d 9e           cmp     r14,    r13     ;
    1114:       05 24           jz      $+12            ;abs 0x1120
    1116:       fe 4f 00 00     mov.b   @r15+,  0(r14)  ;
    111a:       1e 53           inc     r14             ;
    111c:       0e 9d           cmp     r13,    r14     ;
    111e:       fb 2b           jnc     $-8             ;abs 0x1116
    1120:       3f 40 00 02     mov     #512,   r15     ;#0x0200
    1124:       3d 40 02 02     mov     #514,   r13     ;#0x0202
    1128:       0d 9f           cmp     r15,    r13     ;
    112a:       05 24           jz      $+12            ;abs 0x1136
    112c:       cf 43 00 00     mov.b   #0,     0(r15)  ;r3 As==00
    1130:       1f 53           inc     r15             ;
    1132:       0f 9d           cmp     r13,    r15     ;
    1134:       fb 2b           jnc     $-8             ;abs 0x112c
    1136:       30 40 40 11     br      #0x1140         ;

0000113a <__ctors_end>:
    113a:       30 40 3e 11     br      #0x113e         ;

0000113e <_unexpected_>:
    113e:       00 13           reti

00001140 <main>:
    1140:       31 40 fe 09     mov     #2558,  r1      ;#0x09fe
    1144:       04 41           mov     r1,     r4      ;
    1146:       94 52 00 02     add     &0x0200,0(r4)   ;0x0200
    114a:       00 00
    114c:       82 43 00 02     mov     #0,     &0x0200 ;r3 As==00
    1150:       fa 3f           jmp     $-10            ;abs 0x1146
    1152:       21 53           incd    r1              ;
    1154:       30 40 72 11     br      #0x1172         ;

00001158 <timerA1Int>:
    1158:       05 12           push    r5              ;
    115a:       04 12           push    r4              ;
    115c:       92 43 00 02     mov     #1,     &0x0200 ;r3 As==01
    1160:       34 41           pop     r4              ;
    1162:       35 41           pop     r5              ;
    1164:       00 13           reti

00001166 <timerA0Int>:
    1166:       05 12           push    r5              ;
    1168:       04 12           push    r4              ;
    116a:       a2 43 00 02     mov     #2,     &0x0200 ;r3 As==10
    116e:       30 40 8a 11     br      #0x118a         ;

00001172 <__stop_progExec__>:
    1172:       02 df           bis     r15,    r2      ;
    1174:       fe 3f           jmp     $-2             ;abs 0x1172

00001176 <__epilogue_restorer_intr>:
    1176:       34 41           pop     r4              ;
    1178:       35 41           pop     r5              ;
    117a:       36 41           pop     r6              ;
    117c:       37 41           pop     r7              ;
    117e:       38 41           pop     r8              ;
    1180:       39 41           pop     r9              ;
    1182:       3a 41           pop     r10             ;
    1184:       3b 41           pop     r11             ;
    1186:       3c 41           pop     r12             ;
    1188:       3d 41           pop     r13             ;
    118a:       3e 41           pop     r14             ;
    118c:       3f 41           pop     r15             ;
    118e:       00 13           reti
Disassembly of section .vectors:

0000ffe0 <InterruptVectors>:
ffe0: 3a 11 3a 11 3a 11 3a 11 3a 11 58 11 66 11 3a 11 :.:.:.:.:.X.f.:. fff0: 3a 11 3a 11 3a 11 3a 11 3a 11 3a 11 3a 11 00 11 :.:.:.:.:.:.:...

The epilogue_restorer_intr function is called, but the same registers are not pushed onto the start at the start of the interrupt.

I guess that the logic in gcc/config/msp430/msp430.c line 879 is not correct

this is the code
      /* Here, we've got a chance to jump to prologue saver */
      num_saved_regs = msp430_func_num_saved_regs ();

      if ((TARGET_SAVE_PROLOGUE || save_prologue_p)
&& !interrupt_func_p && !arg_register_used[12] && num_saved_regs > 4)
        {
...

what it should be I don't quite know. The __epilogue_restorer_intr seems to be optimised out in my example by using -O2 to compile also.

Thanks,

--
Peter Jansen
STS
Australian Antarctic Division
Channel Highway
Kingston
TAS        7050
AUSTRALIA
Ph  (03) 62 323 533
Fax (03) 62 323 351

Reply via email to