I traced this down to the value range propagation phase in gcc, which is a
tree optimization that occurs long before anything that's MSP430-specific.
This phase replaces the value of i8 with a constant 127 after the first
output.
So I'm gonna have to agree with Michiel that the code relies on undefined
behavior. That assessment is supported by the fact the reproducing code
produces the same result when built with gcc 4.6.3 under Fedora 17
platform, so even if it is a gcc bug it's not specific to msp430.
As for the RH/TI plans: When I last looked a couple weeks ago there was no
evidence of msp430 activity in any of the GNU repositories or mailing
lists, so presumably they're still working internally. My only insight
into the process was from some emails and a telecon shortly after the
announcement, which lead me to think they underestimated the amount of work
required to get binutils to support the chip properly. There is existing
material in upstream binutils that I recommended they throw out (what
mspgcc uses is nearly a complete rewrite), but the RH folks assured me they
"knew all about it" and could fix what was there so we left it at that.
Peter
On Thu, Feb 14, 2013 at 8:18 PM, Rick Kimball <rick.kimb...@gmail.com>wrote:
> I've been working on some C++ template based classes and ran into a
> snag. At first I thought it was related to the C++ templates however
> it turns out when I reduced the code down to a straight 'C'
> implementation I still have the same problem.
>
> The code below has issues with the int8_t data type. In "test 2" i8
> starts at 126 and incrementing it should make it roll over to a
> negative number but it doesn't. This problem appears when i use -Os (
> which is my normal mode of operation ) and does go away if I back off
> and use -O1. If nothing else it would interesting if others try this
> with their version of the compiler. I'm using the linux version that
> ships with Energia:
> gcc version 4.6.3 20120301 (mspgcc LTS 20120406 unpatched) (MSPGCC
> 20120406 (With patches: sf3540953 sf3559978)) Adding volatile to just
> the int8_t declaration will get rid of the problem.
>
> If you use msp430-gcc you might try this code and post your results.
>
> Secondary question, red-hat has been churning away with the msp430-gcc
> code for a while. Is there an ETA for when we might see a new version
> from them?
>
> Thanks,
>
> -rick
>
> code on github: https://gist.github.com/RickKimball/4957969
>
> /**
> * signedtest.c - this fails to output int8_t values properly when
> optimized with -Os
> *
> * Compiled like this:
> *
> * $ msp430-gcc -mmcu=msp430g2553 -DF_CPU=16000000 -Os -Wall \
> * -Wno-main -g -mdisable-watchdog -fdata-sections -ffunction-sections \
> * -Wl,--gc-sections signedtest.c
> *
> * $ mspdebug rf2500 "prog a.out"
> *
> * compiling with -O1 produces proper output, as does changing the
> * int8_t to volatile int8_t
> *
> */
>
> #include <msp430.h>
> #include <stdint.h>
> #include <stdlib.h>
>
> /**
> * serial output routines
> */
> void printc(const char c) {
> while(!(IFG2 & UCA0TXIFG));
> IFG2 &= ~UCA0TXIFG;
> UCA0TXBUF = c;
> }
>
> void prints(const char *s) {
> while(*s)
> printc(*s++);
> }
>
> void printi(int8_t i) {
> char buff[8];
>
> #if 1
> if ( i < 0 ) {
> printc('-');
> i=-i;
> }
> utoa((i & 0xff),buff,10);
> #else
> itoa((int8_t)i,buff,10); /* also tried this, also failed */
> #endif
>
> prints(buff);
> }
>
> void printu(uint8_t i) {
> char buff[8];
>
> utoa((i & 0xff),buff,10);
> prints(buff);
> }
>
> void println() {
> printc('\n');
> }
>
> static const uint32_t brd = (F_CPU + (9600 >> 1)) / 9600; // Bit rate
> divisor
>
> int main(void) {
> uint16_t indx;
>
> #define BAD
>
> #if defined(GOOD)
> volatile int8_t i8; // test2 produces valid results
> #elif defined(BAD)
> int8_t i8; // broken for test2 unless marked volatile or you use -O1
> #endif
> uint8_t u8;
>
> WDTCTL = WDTPW + WDTHOLD; // No watchdog reset
> //
> DCOCTL = 0; // Run at 16 MHz
> BCSCTL1 = CALBC1_16MHZ; //
> DCOCTL = CALDCO_16MHZ; //
>
> //P1DIR |= BIT0 | BIT4; P1SEL |= BIT4;
>
> // GPIO Configuration ; // Set alternate
> function I/O for UART & SPI
> P1SEL |= BIT2; // UART P1.2(tx)
> P1SEL2 |= BIT2;
>
> // Serial Config
> UCA0CTL1 = UCSWRST; // Hold USCI in
> reset to allow configuration
> UCA0CTL0 = 0; // No parity, LSB
> first, 8 bits, one stop bit, UART (async)
> UCA0BR1 = (brd >> 12) & 0xFF; // High byte of whole
> divisor
> UCA0BR0 = (brd >> 4) & 0xFF; // Low byte of whole
> divisor
> UCA0MCTL = ((brd << 4) & 0xF0) | UCOS16; // Fractional
> divisor, oversampling mode
> UCA0CTL1 = UCSSEL_2; // Use SMCLK for bit
> rate generator, release reset
>
>
> prints("-test 1- int8_t=125, uint8_t=125 - signed/unsigned boundary
> rollover\n RESULTS: always succeeds\n");
> i8=125; u8=125;
> for(indx=0; indx < 5; indx++, i8++, u8++) {
> printi(i8);
> prints(", ");
> printu(u8);
> println();
> }
>
> prints("-test 2- int8_t=126, uint8_t=126 - signed/unsigned boundary
> rollover\n RESULTS: fails unless volatile\n");
> i8=126; u8=126;
> for(indx=0; indx < 4; indx++, i8++, u8++) {
> printi(i8);
> prints(", ");
> printu(u8);
> println();
> }
>
> prints("-test 3- int8_t=127, uint8_t=127 - signed/unsigned boundary
> rollover\n RESULTS: always ok\n");
> i8=127; u8=127;
> for(indx=0; indx < 3; indx++, i8++, u8++) {
> printi(i8);
> prints(", ");
> printu(u8);
> println();
> }
>
> while(1);
> }
>
> #if 0
> >>> Bad results when int8_t not volatile
>
> -test 1- int8_t=125, uint8_t=125 - signed/unsigned boundary rollover
> RESULTS: always succeeds
> 125, 125
> 126, 126
> 127, 127
> -128, 128
> -127, 129
> -test 2- int8_t=126, uint8_t=126 - signed/unsigned boundary rollover
> RESULTS: fails unless volatile
> 126, 126
> 127, 127
> 127, 128 << fail this is the wrong result
> 127, 129 << fail this is the wrong result
> -test 3- int8_t=127, uint8_t=127 - signed/unsigned boundary rollover
> RESULTS: always ok
> 127, 127
> -128, 128
> -127, 129
>
>
> >>> Good results when using volatile int8_t
>
> -test 1- int8_t=125, uint8_t=125 - signed/unsigned boundary rollover
> RESULTS: always succeeds
> 125, 125
> 126, 126
> 127, 127
> -128, 128
> -127, 129
> -test 2- int8_t=126, uint8_t=126 - signed/unsigned boundary rollover
> RESULTS: fails unless volatile
> 126, 126
> 127, 127
> -128, 128
> -127, 129
> -test 3- int8_t=127, uint8_t=127 - signed/unsigned boundary rollover
> RESULTS: always ok
> 127, 127
> -128, 128
> -127, 129
>
>
> #endif
>
>
> ------------------------------------------------------------------------------
> Free Next-Gen Firewall Hardware Offer
> Buy your Sophos next-gen firewall before the end March 2013
> and get the hardware for free! Learn more.
> http://p.sf.net/sfu/sophos-d2d-feb
> _______________________________________________
> Mspgcc-users mailing list
> Mspgcc-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mspgcc-users
>
------------------------------------------------------------------------------
Free Next-Gen Firewall Hardware Offer
Buy your Sophos next-gen firewall before the end March 2013
and get the hardware for free! Learn more.
http://p.sf.net/sfu/sophos-d2d-feb
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users