Folks,
it turns out that this should be a bug in the compiler as well as in the gdb sim target.
Since CALL decrements the stack pointer to save the return address, a register indexed call using the stack pointer must account for this.
The SP is decremented before the address of the target operand is calculated;
thus, for a SP indexed call, the index must be incremented by 2.
If you want to call a function whose address is located at SP+2, the opcode should be "call
4(r1)". However, gcc generates a "call 2(r1)".
This applies to all the addressing modes using a register. So, a "call @r1" ("call
0(r1)") would save the return address to the stack, then jump to the return address. BAD. And a
"call r1" obviously makes no sense anyway.
For reference, see page 3-29 of slau49 (MSP430x1xx Family User's Guide).
Heiko
Heiko Panther wrote:
Followup. Here's a self-contained demo of the problem. Compiles with
msp430-gcc main.S -mmcu=msp430x133 -o main.elf
Watch it run and check that while 2(r1) contains the address of correct(),
actually wrong() is called. Tried with an M430F133 as well an M430F147.
Best,
Heiko
------------------------------------------------------------------------
.file "main.c"
.arch msp430x133
.text
.p2align 1,0
correct:
push r14
pop r14
ret
.p2align 1,0
wrong:
push r15
pop r15
ret
.p2align 1,0
.global main
.type main,@function
main:
mov #0x300, r1
sub #4, r1
mov #correct, 2(r1)
mov #wrong, 0(r1)
call 2(r1)
add #4, r1
br #__stop_progExec__