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