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