I don't see anything wrong here. Except for the concept of this call.
Right before the call instruction, R1 points to mem, so the compiler uses R1 as 
the source for the call address.
But what does the processor do?
If it is instructed to CALL R1, it will push the return address on stack, then 
decrements R1 and then jumps to the given address. Unfortunately, the address 
was in R1 and R1 has been changed by teh last microcode 
step. The processor does not care for the case that the call destination is R1. 
It just takes the current value and moves it into R0.

Think of it as a macro

#define call(x) \
sub #2,r1 \
mov r0,@r1 \
mov x,r0 

If you set x=r1, it won't work as expected.

All this happens outside the control (and knowledge) of the compiler and of 
course causes a bad jump. The compiler does not analyze internal microcode 
sub-steps when optimizing.

On the MSP5438, the errata sheet lists

> CPU26 CPU Module
> Function CALL SP does not behave as expected
> Description When the intention is to execute code from the stack, a CALL SP 
> instruction skips the
> first piece of data (instruction) on the stack. The second piece of data at 
> SP + 2 is used
> as the first executable instruction.
> Workaround Write the op code for a NOP as the first instruction on the stack. 
> Begin the intended
> subroutine at address SP + 2.

which actually counteracts the effect that SP is decremented. Well, I'm not 
sure whether it just counteracts this effect or even calls mem+2. My guess is 
that it has to do with the 430X instruction set.

Nevertheless, you can easily circumvent the problem by changing your code to 

    unsigned char mem[102];
    register void (*badcall)(void) = (void *)(mem+2);

which gives the (then) expected result

                badguy:
                sub     #102, r1        ;       102, fpn 0
                mov     r1, r15 
                add     #llo(2), r15
                call    r15
                add     #102, r1
                ret

The same effect is acquired if you have some more local variables which are 
placed on the stack AFTER mem. In this case too, R1 doesn't point to mem 
anymore and therefore isn't used for the call.

Or you do it yourself in assembly...

__asm__ __volatile __ ( "mov r1 , r15 \r\n call r1":::"r15");


But after all, I must admit, the compiler should not generate a 'call r1' or 
'call sp' instruction (and also not a "call x(sp)" which could be imagined for 
a jump table on the stack) at all. So well, one could consider it a 
compiler bug. Or rather an optimisation bug. If you disable optimisation, the 
compiler will properly generate some much too complex code that does the 'right 
thing' too.

JMGross

----- Ursprüngliche Nachricht -----
Von: thilo
An: [email protected]
Gesendet am: 25 Mrz 2010 08:43:25
Betreff: [Mspgcc-users] compiler bug in gcc 3.2.3/msp430 - calling a function 
on the local stack will jump to the wrong address *(--sp)

Hello,

is this a known bug ?

The compiler generates wrong code for:
=======
void badguy()
{
    unsigned char mem[100];
    register void (*badcall)(void) = (void *)mem;
    (*badcall)();      // this will call mem[-2]
}
========
The bits it does are:
=======================
badguy:
        sub     #100, r1        ;       100, fpn 0
        /* prologue end (size=2) */

        call    r1       ;  12  *call_insn/1    [length = 1]

        /* epilogue: frame size=100 */
        add     #100, r1
        ret
===============
The msp2274 that I was using, is FIRST decrementing the SP (r1) and then
calling it. 
 msp430-gcc   -O2 -mmcu=msp430x2274 -Werror  -dp  -S  tfun.c

Is 3.2.3 still the latest supported compiler?
thanks
thilo





------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Mspgcc-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users


Reply via email to