This demonstrates an apparent compiler bug in msp430-gcc, using a
compiler built 30 Sept 2003 from CVS. An older compiler version dating
from 31 March 2003 produced the same problem. The demonstration
routine is a hacked-out fragment from some real code, and makes little
sense in isolation, but is about the minimal code to show the bug.

The C source is:

###########################################################################

// BUG.C demonstrates a compiler bug

#define FULL_SCALE 4095

int p_offset, q_offset;

void set_offsets( int p_off, int q_off )
//
// Offsets in tenths of full scale
{
  p_offset = ( p_off * FULL_SCALE ) / 10;
  q_offset = ( q_off * FULL_SCALE ) / 10;
}

###########################################################################

Compiled with:

msp430-gcc -S -mmcu=msp430x149 -O2 bug.c

This produces correct code:

###########################################################################

        .file   "bug.c"
        .arch msp430x149

/* Hardware multiplier registers: */
__MPY=0x130
__MPYS=0x132
__MAC=0x134
__MACS=0x136
__OP2=0x138
__RESLO=0x13a
__RESHI=0x13c
__SUMEXT=0x13e

        .text
        .p2align 1,0
.global set_offsets
        .type   set_offsets,@function
/***********************
 * Function `set_offsets' 
 ***********************/
set_offsets:
/* prologue: frame size = 0 */
.L__FrameSize_set_offsets=0x0
.L__FrameOffset_set_offsets=0x6
        push    r11
        push    r10
        push    r9
/* prologue end (size=3) */
        mov     r14, r9 
        push    r2
        dint
        nop
        mov     r15, &__MPYS
        mov     #llo(4095), &__OP2
        mov     &__RESLO, r15
        pop     r2
        mov     r15, r12 
        mov     #llo(10), r10 
        call    #__divmodhi4
        mov     r12, &p_offset 
        push    r2
        dint
        nop
        mov     r9, &__MPYS
        mov     #llo(4095), &__OP2
        mov     &__RESLO, r15
        pop     r2
        mov     r15, r12 
        mov     #llo(10), r10 
        call    #__divmodhi4
        mov     r12, &q_offset 
/* epilogue: frame size=0 */
        pop     r9
        pop     r10
        pop     r11
        ret
/* epilogue end (size=4) */
/* function set_offsets size 42 (35) */
.Lfe1:
        .size   set_offsets,.Lfe1-set_offsets
/********* End of function ******/

        .comm p_offset,2,2
        .comm q_offset,2,2

/*********************************************************************
 * File bug.c: code size: 42 words (0x2a)
 * incl. words in prologues: 3, epilogues: 4
 *********************************************************************/

###########################################################################

Compiled with:

msp430-gcc -S -mmcu=msp430x149 -O2 -mnoint-hwmul bug.c

Which differs only in the addition of the -mnoint-hwmul switch, it
produces code which incorrectly sets the q_offset to the same value as
the p_offset. The calculation for q_offset starts correctly, but the
code to perform the division by ten is omitted, so that R12 still
contains the result of the previous calculation. The added comment
with all the queries pinpoints the error.

###########################################################################

        .file   "bug.c"
        .arch msp430x149

/* Hardware multiplier registers: */
__MPY=0x130
__MPYS=0x132
__MAC=0x134
__MACS=0x136
__OP2=0x138
__RESLO=0x13a
__RESHI=0x13c
__SUMEXT=0x13e

        .text
        .p2align 1,0
.global set_offsets
        .type   set_offsets,@function
/***********************
 * Function `set_offsets' 
 ***********************/
set_offsets:
/* prologue: frame size = 0 */
.L__FrameSize_set_offsets=0x0
.L__FrameOffset_set_offsets=0x8
        push    r11
        push    r10
        push    r9
        push    r8
/* prologue end (size=4) */
        mov     r14, r8 
        mov     r15, &__MPYS
        mov     #llo(4095), &__OP2
        mov     &__RESLO, r12 
        mov     #llo(10), r10 
        call    #__divmodhi4
        mov     r12, &p_offset 
        mov     r8, &__MPYS
        mov     #llo(4095), &__OP2
/* ???????????????????????????????????????????????????????????????????
                      Some code was missed here
??????????????????????????????????????????????????????????????????? */
        mov     r12, &q_offset 
/* epilogue: frame size=0 */
        pop     r8
        pop     r9
        pop     r10
        pop     r11
        ret
/* epilogue end (size=5) */
/* function set_offsets size 30 (21) */
.Lfe1:
        .size   set_offsets,.Lfe1-set_offsets
/********* End of function ******/

        .comm p_offset,2,2
        .comm q_offset,2,2

/*********************************************************************
 * File bug.c: code size: 30 words (0x1e)
 * incl. words in prologues: 4, epilogues: 5
 *********************************************************************/

###########################################################################

-- 
Rick Jenkins <r...@hartmantech.com>
Hartman Technica           http://www.hartmantech.com 
Phone +1 (403) 230-1987 voice & fax
221 35 Avenue. N.E., Calgary, Alberta, Canada T2E 2K5


Reply via email to