There is something _really_ odd.
The listing file you've generated is incomplete. For example,
jmp &0x000
bic rN, &0x000
is impossible.
Also, try to use something like gcc-3.2.3, not a pre-release.
~d
Tommy Andersson wrote:
> Hello maintainers,
>
> I am using msp430-gcc and friends, and I have found some possible
> bugs. My computer is setup according to:
>
> cat /etc/slackware-version
> Slackware 9.0.0
>
> uname -a
> Linux gaston 2.4.20 #2 Mon Mar 17 22:02:15 PST 2003 i686 unknown
>
> I have included some source-code in this message, which begins at
> "Listing 1", and also some assembly output which begins at
> "Listing 2". The following files have been downloaded and installed:
>
> msp430-gcc-3.2.2.20030214.tar.bz2
> msp430-libc-1.0.20030207.tar.bz2
>
> The commandline used to compile the program in listing 1 was:
>
> msp430-gcc -O -S -fpeephole -fpeephole2 -mmcu=msp430x147 bugsdemo.c -o
> bugsdemo.s
>
> The reason that I activated the flag -fpeephole2, was that I was not
> satisfied with the optimization when using the datatype long int. The
> flag made the optimizer remove a few redundant instructions, but also,
> as we will see, a few necessary instructions as well.
>
> Now to the details:
>
> 1. Sourcecode line 63 and line 74 generates an invalid opcode, "jne
> &0x0000", as can be seen in lines 44 and 61 in the assembly
> listing. The workaround was to rewrite the macros DISABLE_TX_INTR
> and ENABLE_TX_INTR to generate function calls. This is not a very
> efficient way of coding however.
>
> 2. Sourcecode line 137 generates an invalid opcode, "jl &0x001D", as
> can be seen in line 151 in the assembly listing. The workaround was
> to rewrite the macro DATA_DIR_OUT to generate a function call. The
> phenomenom seems to be related the one above.
>
> 3. Lines 237 to 244 have an #if/#else/#endif macro. If the first case
> is compiled, the value of grid[0] will not be correct when the call
> to pr_txchar( grid[0] ) in line 239 is made. A "mov @r11, r15"
> between lines 266 and 267 would save the day. The second case of
> the macro always compile correctly. During the writing of this
> message I found that the problem disappeared when I omitted the
> flag -fpeephole2 on the commandline. The commndline now was:
> msp430-gcc -O -S -fpeephole -mmcu=msp430x147 bugsdemo.c -o bugsdemo.s
>
> I do not know if -O automatically sets -fpeephole, is there any way of
> checking this ?
>
> NOTE that the line-numbers above refers to line-numbers in the source,
> not to line-numbers in this text.
>
> The code in the example below is copied from different files in
> production code.
>
> With Best Regards, Tommy Andersson
>
> [email protected]
>
> --- Listing 1 begins here ---------------------------------------
> #include <io.h>
> #include <signal.h>
>
> #define ENABLE_TX_INTR SFR_CMD(bis.b,IE1,UTXIE0)
> #define DISABLE_TX_INTR SFR_CMD(bic.b,IE1,UTXIE0)
>
> #define U0_BUFSIZE 10
> #define PRC_PRINTER 2
>
> // Push flags and disable interrupts
> inline static void pushf_disable( void )
> {
> asm volatile ( "push r2 \n\t" : : );
> dint();
> asm volatile ( "nop \n\t" : : ); // dint() is delayed 1 clock !
> }
>
> // Pop the flags, possibly enabling interrupts
> inline static void popf( void )
> {
> asm volatile ( "pop r2 \n\t" : : );
> }
>
> typedef unsigned char BYTE;
>
> /*** Global control variables: ***/
> extern volatile unsigned char curr_pid;
>
> /*----------------------------------------------------------------------
> Local variables
> ----------------------------------------------------------------------*/
> static volatile BYTE tx0_buffer[U0_BUFSIZE];
> static volatile BYTE *tx0_head = tx0_buffer;
> static volatile BYTE *tx0_tail = tx0_buffer;
>
> static volatile BYTE tx0_stop;
> static volatile BYTE tx0_pending;
>
> static volatile BYTE suspended, wait_data_flag;
>
> /*----------------------------------------------------------------------
> Transmit a character through the serial interface. Returns -1 on a
> failure, otherwise 0 is returned.
> ----------------------------------------------------------------------*/
> int pr_txchar( char ch )
> {
> BYTE *ptr;
>
> retry:
> DISABLE_TX_INTR;
>
> if ( !tx0_pending ) { // NO pending transmissions
> U0TXBUF = ch;
> tx0_pending = 1;
> }
> else {
> ptr = tx0_head;
> if (++ptr >= tx0_buffer+U0_BUFSIZE)
> ptr = tx0_buffer;
> if (ptr == tx0_tail) { // Buffer is FULL !
> ENABLE_TX_INTR;
>
> if ( curr_pid == PRC_PRINTER ) {
> pushf_disable();
> suspended = 1; // This flag MUST BE SET before suspending the proc !
> proc_suspend( PRC_PRINTER ); // Suspend printer process
> popf();
> goto retry;
> }
> else
> return -1; // Otherwise, return error.
> }
> *tx0_head = ch; // Save next printer character.
> tx0_head = ptr;
> }
> ENABLE_TX_INTR;
> return 0;
> }
>
> #define CLOCK_LOW SFR_CMD( bic, P4OUT, 1<<0 )
> #define CLOCK_HIGH SFR_CMD( bis, P4OUT, 1<<0 )
> #define DATA_LOW SFR_CMD( bic, P4OUT, 1<<1 )
> #define DATA_HIGH SFR_CMD( bis, P4OUT, 1<<1 )
> #define DATA_DIR_IN SFR_CMD( bic, P4DIR, 1<<1 )
> #define DATA_DIR_OUT SFR_CMD( bis, P4DIR, 1<<1 )
> #define DATA_IN (P4IN&(1<<1))
>
> /*----------------------------------------------------------------------
> Read one byte of data from the RTC.
>
> The argument 'bytecount' shall be assigned the number of to be read at
> this 'session', and is used to control the acknowledge bit.
> ----------------------------------------------------------------------*/
> static unsigned char rtc_read( signed char bytecount )
> {
> unsigned char bitcount, data_read;
> static signed char count;
>
> if (bytecount)
> count = bytecount-1;
> else
> --count;
>
> DATA_DIR_IN; // DATA goes high (hi-z)
> for (bitcount = 0; bitcount < 8; bitcount++ ) {
> CLOCK_HIGH;
> delay_us( 4 );
>
> data_read <<= 1;
> if ( DATA_IN )
> data_read |= (1<<0);
> else
> data_read &= ~(1<<0);
>
> CLOCK_LOW;
> delay_us( 4 );
> }
> DATA_LOW;
>
> if ( count > 0 )
> DATA_DIR_OUT; // DATA goes low -> Acknowledge */
>
> delay_us( 2 );
> CLOCK_HIGH;
> delay_us( 4 );
> CLOCK_LOW;
> delay_us( 2 );
> DATA_DIR_IN;
>
> return data_read;
> }
>
> #define LF 10
> #define FF 12
> #define CR 13
> #define ESC 27
>
> #define WIDTH_CHAR 12
> #define WIDTH_PRINTROW 400
> #define MAXWIDTH_PRINTROW
> (WIDTH_PRINTROW>WIDTH_LOGO?WIDTH_PRINTROW:WIDTH_LOGO)
> #define LOGO_HORZ_TAB ((480-300)/2)
> #define HDR_HORZ_TAB 49
> #define DATA_HORZ_TAB 49
> #define FOOT_HORZ_TAB 49
> #define HEIGHT_TEXTLINE 12
> #define HEIGHT_PRINTROW 8
> #define HEIGHT_FOOTER (12*HEIGHT_TEXTLINE)
> #define HEIGHT_A4 ((int)(VERT_DPI*297/25.4))
> #define HORZ_GRIDLINE_SPACE 30
> #define COARSE_VERT_GRIDLINE_SPACE 67
> #define FINE_VERT_GRIDLINE_SPACE 100
> #define CURVE_WIDTH 3
>
> #define PC_BEGIN_LOGO {pr_txchar(ESC);pr_txchar('L');\
> pr_txchar((WIDTH_LOGO+LOGO_HORZ_TAB)&0xff);\
> pr_txchar((WIDTH_LOGO+LOGO_HORZ_TAB)>>8);}
> #define PC_BEGIN_HDRTAB {pr_txchar(ESC);pr_txchar('L');\
> pr_txchar(LOGO_HORZ_TAB&0xff);\
> pr_txchar(LOGO_HORZ_TAB>>8);}
> #define PC_BEGIN_GRAPHIC {pr_txchar(ESC);pr_txchar('L');\
> pr_txchar((WIDTH_PRINTROW)&0xff);\
> pr_txchar((WIDTH_PRINTROW)>>8);}
> #define PC_BEGIN_GRA_RMV {pr_txchar(ESC);pr_txchar('L');\
> pr_txchar((WIDTH_PRINTROW+5)&0xff);\
> pr_txchar((WIDTH_PRINTROW+5)>>8);}
> #define PC_SET_LINESPACING(x) {pr_txchar(ESC);pr_txchar('A');pr_txchar(x);}
> #define PC_SET_GRLINESPACING {pr_txchar(ESC);pr_txchar('A');pr_txchar(8);}
> #define PC_SET_TXTLINESPACING {pr_txchar(ESC);pr_txchar('A');pr_txchar(12);}
> #define PC_SELECT_CHARSET(x) {pr_txchar(ESC);pr_txchar('R');pr_txchar(x);\
> pr_txchar(ESC);pr_txchar('t');pr_txchar(x);}
> #define PC_CRLF {pr_txchar(CR);pr_txchar(LF);}
> #define PC_PIXELTAB(x) {int q;pr_txchar(ESC);pr_txchar('L');\
> pr_txchar((x)&0xff);pr_txchar((x)>>8);\
> for(q=(x);q;q--)pr_txchar(0);}
> #define PC_FEED pr_txchar(FF)
> #define PC_SET_CONDENSED pr_txchar(0x0f)
> #define PC_SET_NORMAL pr_txchar(0x12)
>
> static int timeaxis;
>
> unsigned char *make_grid_and_frame( int horz_pos, int vert_pos );
> unsigned char create_data_curve( int pos );
>
> int print_data( void )
> {
> int printbyte;
> unsigned char vline8, *grid;
>
> PC_SET_GRLINESPACING;
> // Left margin
> grid = make_grid_and_frame( 0, timeaxis );
> if (grid[1] != 128) {
> #if (DATA_HORZ_TAB - 4*WIDTH_CHAR -1) < 0
> #error "***** Not enough space for numeric scale at left edge *****"
> #else
> #if (DATA_HORZ_TAB - 4*WIDTH_CHAR -1) > 0
> PC_PIXELTAB(DATA_HORZ_TAB - 4*WIDTH_CHAR -1);
> #endif
> #endif
>
> pr_txnum_i( (timeaxis+7-grid[1])/3, 3 ); pr_txchar( 's' );
> PC_PIXELTAB(1);
> }
> else
> PC_PIXELTAB(DATA_HORZ_TAB);
>
> // Data
> PC_BEGIN_GRA_RMV;
>
> for (printbyte = 0; printbyte<WIDTH_PRINTROW; printbyte++ ) {
> grid = make_grid_and_frame( printbyte, timeaxis );
> #ifndef COMPILER_BUG // This does not work due to a compiler bug
> grid[0] |= create_data_curve( printbyte );
> pr_txchar( grid[0] );
> #else
> vline8 = grid[0];
> vline8 |= create_data_curve( printbyte );
> pr_txchar( vline8 );
> #endif
> }
> pr_txchar( 0 );
> pr_txchar( 0 );
> vline8 = create_rmv8( printbyte );
> pr_txchar( vline8 );
> pr_txchar( vline8 );
> pr_txchar( vline8 );
> PC_CRLF;
>
> timeaxis += 8;
> return HEIGHT_PRINTROW;
> }
>
> --- Listing 2 begins here ---------------------------------------
> .file "bugsdemo.c"
> .arch msp430x147
>
> /* Hardware multiplier registers: */
> __MPY=0x130
> __MPYS=0x132
> __MAC=0x134
> __MACS=0x136
> __OP2=0x138
> __RESLO=0x13a
> __RESHI=0x13c
> __SUMEXT=0x13e
>
> .data
> .p2align 1,0
> .type tx0_head,@object
> .size tx0_head,2
> tx0_head:
> .short tx0_buffer
> .p2align 1,0
> .type tx0_tail,@object
> .size tx0_tail,2
> tx0_tail:
> .short tx0_buffer
> .text
> .p2align 1,0
> .global pr_txchar
> .type pr_txchar,@function
> /***********************
> * Function `pr_txchar'
> ***********************/
> pr_txchar:
> /* prologue: frame size = 0 */
> .L__FrameSize_pr_txchar=0x0
> .L__FrameOffset_pr_txchar=0x2
> push r11
> /* prologue end (size=1) */
> mov.b r15, r11
> .L2:
> /* #APP */
> bic.b #llo(-128), &0x0000
> /* #NOAPP */
> cmp.b #llo(0), &tx0_pending
> jne &0x0000
> mov.b r11, &0x0077
> mov.b #llo(1), &tx0_pending
> jmp .L4
> .L3:
> mov &tx0_head, r14
> add #llo(1), r14
> cmp #tx0_buffer+10, r14
> jlo .L5
> mov #tx0_buffer, r14
> .L5:
> cmp &tx0_tail, r14
> jne .L6
> /* #APP */
> bis.b #llo(-128), &0x0000
> /* #NOAPP */
> cmp.b #llo(2), &curr_pid
> jne &0x0000
> /* #APP */
> push r2
>
> dint
> nop
>
> /* #NOAPP */
> mov.b #llo(1), &suspended
> mov #llo(2), r15
> call #proc_suspend
> /* #APP */
> pop r2
>
> /* #NOAPP */
> jmp .L2
> .L7:
> mov #llo(-1), r15
> jmp .L1
> .L6:
> mov &tx0_head, r15
> mov.b r11, @r15
> mov r14, &tx0_head
> .L4:
> /* #APP */
> bis.b #llo(-128), &0x0000
> /* #NOAPP */
> mov #llo(0), r15
> .L1:
> /* epilogue: frame size=0 */
> pop r11
> ret
> /* epilogue end (size=2) */
> /* function pr_txchar size 64 (61) */
> .Lfe1:
> .size pr_txchar,.Lfe1-pr_txchar
> /********* End of function ******/
>
> .local count.0
> .comm count.0,1
> .p2align 1,0
> .type rtc_read,@function
> /***********************
> * Function `rtc_read'
> ***********************/
> rtc_read:
> /* prologue: frame size = 0 */
> .L__FrameSize_rtc_read=0x0
> .L__FrameOffset_rtc_read=0x4
> push r11
> push r10
> /* prologue end (size=2) */
> cmp.b #llo(0), r15
> jeq .L12
> add.b #llo(-1), r15
> mov.b r15, &count.0
> jmp .L13
> .L12:
> add.b #llo(-1), &count.0
> .L13:
> /* #APP */
> bic #llo(2), &0x001E
> /* #NOAPP */
> mov.b #llo(0), r10
> .L20:
> /* #APP */
> bis #llo(1), &0x001D
> /* #NOAPP */
> mov #llo(4), r15
> call #delay_us
> rla.b r11
> bit.b #llo(2),&0x001C
> jeq .L18
> bis.b #llo(1), r11
> jmp .L19
> .L18:
> bic.b #llo(1),r11
> .L19:
> /* #APP */
> bic #llo(1), &0x001D
> /* #NOAPP */
> mov #llo(4), r15
> call #delay_us
> add.b #llo(1), r10
> cmp.b #llo(8), r10
> jlo .L20
> /* #APP */
> bic #llo(2), &0x001D
> /* #NOAPP */
> cmp.b #llo(1), &count.0
> jl &0x001D ; &0x001D
> /* #APP */
> bis #llo(2), &0x001E
> /* #NOAPP */
> .L21:
> mov #llo(2), r15
> call #delay_us
> /* #APP */
> bis #llo(1), &0x001D
> /* #NOAPP */
> mov #llo(4), r15
> call #delay_us
> /* #APP */
> bic #llo(1), &0x001D
> /* #NOAPP */
> mov #llo(2), r15
> call #delay_us
> /* #APP */
> bic #llo(2), &0x001E
> /* #NOAPP */
> mov.b r11, r15
> /* epilogue: frame size=0 */
> pop r10
> pop r11
> ret
> /* epilogue end (size=3) */
> /* function rtc_read size 61 (56) */
> .Lfe2:
> .size rtc_read,.Lfe2-rtc_read
> /********* End of function ******/
>
> .p2align 1,0
> .global print_data
> .type print_data,@function
> /***********************
> * Function `print_data'
> ***********************/
> print_data:
> /* prologue: frame size = 0 */
> .L__FrameSize_print_data=0x0
> .L__FrameOffset_print_data=0x4
> push r11
> push r10
> /* prologue end (size=2) */
> mov.b #llo(27), r15
> call #pr_txchar
> mov.b #llo(65), r15
> call #pr_txchar
> mov.b #llo(8), r15
> call #pr_txchar
> mov &timeaxis, r14
> mov #llo(0), r15
> call #make_grid_and_frame
> cmp.b #llo(-128), 1(r15)
> jeq .L25
> mov.b 1(r15), r15
> mov &timeaxis, r14
> sub r15, r14
> mov r14, r15
> add #llo(7), r15
> mov r15, r12
> mov #llo(3), r10
> call #__divmodhi4
> mov r12, r15
> mov #llo(3), r14
> call #pr_txnum_i
> mov.b #llo(115), r15
> call #pr_txchar
> mov.b #llo(27), r15
> call #pr_txchar
> mov.b #llo(76), r15
> call #pr_txchar
> mov.b #llo(1), r15
> call #pr_txchar
> mov.b #llo(0), r15
> call #pr_txchar
> mov #llo(1), r11
> .L30:
> mov.b #llo(0), r15
> call #pr_txchar
> add #llo(-1), r11
> jeq .L31
> jmp .L30
> .L25:
> mov.b #llo(27), r15
> call #pr_txchar
> mov.b #llo(76), r15
> call #pr_txchar
> mov.b #llo(49), r15
> call #pr_txchar
> mov.b #llo(0), r15
> call #pr_txchar
> mov #llo(49), r11
> .L36:
> mov.b #llo(0), r15
> call #pr_txchar
> add #llo(-1), r11
> jne .L36
> .L31:
> mov.b #llo(27), r15
> call #pr_txchar
> mov.b #llo(76), r15
> call #pr_txchar
> mov.b #llo(-107), r15
> call #pr_txchar
> mov.b #llo(1), r15
> call #pr_txchar
> mov #llo(0), r10
> .L41:
> mov &timeaxis, r14
> mov r10, r15
> call #make_grid_and_frame
> mov r15, r11
> mov r10, r15
> call #create_data_curve
> bis.b r15, @r11
> call #pr_txchar
> add #llo(1), r10
> cmp #llo(400), r10
> jl .L41 ; .L41
> mov.b #llo(0), r15
> call #pr_txchar
> mov.b #llo(0), r15
> call #pr_txchar
> mov r10, r15
> call #create_rmv8
> mov r15, r11
> call #pr_txchar
> mov.b r11, r15
> call #pr_txchar
> mov.b r11, r15
> call #pr_txchar
> mov.b #llo(13), r15
> call #pr_txchar
> mov.b #llo(10), r15
> call #pr_txchar
> add #llo(8), &timeaxis
> mov #llo(8), r15
> /* epilogue: frame size=0 */
> pop r10
> pop r11
> ret
> /* epilogue end (size=3) */
> /* function print_data size 153 (148) */
> .Lfe3:
> .size print_data,.Lfe3-print_data
> /********* End of function ******/
>
> .local tx0_buffer
> .comm tx0_buffer,10,2
> .local tx0_stop
> .comm tx0_stop,1
> .local tx0_pending
> .comm tx0_pending,1
> .local suspended
> .comm suspended,1
> .local wait_data_flag
> .comm wait_data_flag,1
> .local timeaxis
> .comm timeaxis,2,2
>
> /*********************************************************************
> * File bugsdemo.c: code size: 278 words (0x116)
> * incl. words in prologues: 5, epilogues: 8
> *********************************************************************/
>
> --- End Of File ---------------------------------------
>
> -------------------------------------------------------
> This SF.Net email is sponsored by: YOU BE THE JUDGE. Be one of 170
> Project Admins to receive an Apple iPod Mini FREE for your judgement on
> who ports your project to Linux PPC the best. Sponsored by IBM.
> Deadline: Sept. 24. Go here: http://sf.net/ppc_contest.php
> _______________________________________________
> Mspgcc-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/mspgcc-users