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__



Reply via email to