while(flag)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

while(flag)

Ian Chapman
Hi all,
      I'm having difficulty understanding this situation.
flag = 1;
while ( 0 != flag )
{
code;
}
  generates strange assembly code till I commented out
// flag = 1;
it looked to me like the optimizer realized that from then on the code
would be planted in a " $  jmp  $; " situation.  I intended flag to be
cleared after an ADC interrupt.  ie set flag and wait for it to be cleared.
Test code snippet and Makefile follow.

Any comment greatly appreciated.  Ian.

/*    Test of while loop msp430 version of gnu c */

#include <msp430.h>
void funct1(void);
int flag, temp, temp2;

int main(void)
{
     WDTCTL = WDTPW + WDTHOLD;                 // Disable watchdog timer
//    Internal clock to 8MHz
     DCOCTL = CALDCO_1MHZ;    //Page 3 device specific data sheet.
     BCSCTL1 = CALBC1_1MHZ;    // ---"""---
     BCSCTL2 = 0;
     BCSCTL3 = 0;
//    flag = 1;  //The optimization makes a mess till I commented this out.
     temp = 0;

     while( 0 != flag )  //flag = 0 from Interrupt routine.
         {
             temp2 ++;  //This did not help
         }

     funct1();
     temp2 = temp;
return 1;
}

void funct1(void) {
temp ++;
}

Makefile
CC=msp430-gcc
CFLAGS=-Os -Wall -g -mmcu=msp430g2553
#CFLAGS=-Os -Wall -g -mmcu=msp430f5438a
OBJ = while.o
%.o: %.c $(DEPS)
     $(CC) -c -o $@ $< $(CFLAGS)
while: $(OBJ)
     $(CC) -o $@.elf $^ $(CFLAGS)
Dis assembly
main:
     0c03e: b2 40 80 5a 20 01         MOV     #0x5a80, &0x0120
     0c044: d2 42 fe 10 56 00         MOV.B   &0x10fe, &0x0056
     0c04a: d2 42 ff 10 57 00         MOV.B   &0x10ff, &0x0057
     0c050: c2 43 58 00               CLR.B   &0x0058
     0c054: c2 43 53 00               CLR.B   &0x0053
     0c058: 92 43 02 02               MOV     #0x0001, &flag
     0c05c: 82 43 04 02               CLR     &temp
     0c060: ff 3f                     JMP     0xc060 //Planted
     0c062: 32 d0 f0 00               BIS     #0x00f0, SR  //Clks/cpu off?
     0c066: fd 3f                     JMP     0xc062
     0c068: 30 40 72 c0               BR      #0xc072
funct1:
     0c06c: 92 53 04 02               INC     &temp
     0c070: 30 41                     RET
     0c072: 00 13                     RETI
     0c074: ff ff ff ff               AND.B   @R15+,  0xffff(R15)
     0c078: ff ff
(mspdebug)


------------------------------------------------------------------------------
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: while(flag)

David W. Schultz
On 11/08/2015 04:01 PM, Ian Chapman wrote:
> Hi all,
>       I'm having difficulty understanding this situation.
> flag = 1;
> while ( 0 != flag )
> {
> code;
> }

If flag is changed within an interrupt, it must be declared as volatile:

volatile int flag;

Otherwise the compiler will see that it never changes and optimize
accordingly.

--
David W. Schultz
http://home.earthlink.net/~david.schultz
Returned for Regrooving



------------------------------------------------------------------------------
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: while(flag)

Wayne Uroda-3
In reply to this post by Ian Chapman
"flag" should be marked volatile, otherwise the optimiser may see it never changes inside the body of the loop and omit checking the flag entirely.

- Wayne

> On 9 Nov 2015, at 08:01, Ian Chapman <[hidden email]> wrote:
>
> Hi all,
>      I'm having difficulty understanding this situation.
> flag = 1;
> while ( 0 != flag )
> {
> code;
> }
>  generates strange assembly code till I commented out
> // flag = 1;
> it looked to me like the optimizer realized that from then on the code
> would be planted in a " $  jmp  $; " situation.  I intended flag to be
> cleared after an ADC interrupt.  ie set flag and wait for it to be cleared.
> Test code snippet and Makefile follow.
>
> Any comment greatly appreciated.  Ian.
>
> /*    Test of while loop msp430 version of gnu c */
>
> #include <msp430.h>
> void funct1(void);
> int flag, temp, temp2;
>
> int main(void)
> {
>     WDTCTL = WDTPW + WDTHOLD;                 // Disable watchdog timer
> //    Internal clock to 8MHz
>     DCOCTL = CALDCO_1MHZ;    //Page 3 device specific data sheet.
>     BCSCTL1 = CALBC1_1MHZ;    // ---"""---
>     BCSCTL2 = 0;
>     BCSCTL3 = 0;
> //    flag = 1;  //The optimization makes a mess till I commented this out.
>     temp = 0;
>
>     while( 0 != flag )  //flag = 0 from Interrupt routine.
>         {
>             temp2 ++;  //This did not help
>         }
>
>     funct1();
>     temp2 = temp;
> return 1;
> }
>
> void funct1(void) {
> temp ++;
> }
>
> Makefile
> CC=msp430-gcc
> CFLAGS=-Os -Wall -g -mmcu=msp430g2553
> #CFLAGS=-Os -Wall -g -mmcu=msp430f5438a
> OBJ = while.o
> %.o: %.c $(DEPS)
>     $(CC) -c -o $@ $< $(CFLAGS)
> while: $(OBJ)
>     $(CC) -o $@.elf $^ $(CFLAGS)
> Dis assembly
> main:
>     0c03e: b2 40 80 5a 20 01         MOV     #0x5a80, &0x0120
>     0c044: d2 42 fe 10 56 00         MOV.B   &0x10fe, &0x0056
>     0c04a: d2 42 ff 10 57 00         MOV.B   &0x10ff, &0x0057
>     0c050: c2 43 58 00               CLR.B   &0x0058
>     0c054: c2 43 53 00               CLR.B   &0x0053
>     0c058: 92 43 02 02               MOV     #0x0001, &flag
>     0c05c: 82 43 04 02               CLR     &temp
>     0c060: ff 3f                     JMP     0xc060 //Planted
>     0c062: 32 d0 f0 00               BIS     #0x00f0, SR  //Clks/cpu off?
>     0c066: fd 3f                     JMP     0xc062
>     0c068: 30 40 72 c0               BR      #0xc072
> funct1:
>     0c06c: 92 53 04 02               INC     &temp
>     0c070: 30 41                     RET
>     0c072: 00 13                     RETI
>     0c074: ff ff ff ff               AND.B   @R15+,  0xffff(R15)
>     0c078: ff ff
> (mspdebug)
>
>
> ------------------------------------------------------------------------------
> _______________________________________________
> Mspgcc-users mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/mspgcc-users

------------------------------------------------------------------------------
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: while(flag)

Daniel Beer-3
In reply to this post by Ian Chapman
On Sun, Nov 08, 2015 at 05:01:34PM -0500, Ian Chapman wrote:

> Hi all,
>       I'm having difficulty understanding this situation.
> flag = 1;
> while ( 0 != flag )
> {
> code;
> }
>   generates strange assembly code till I commented out
> // flag = 1;
> it looked to me like the optimizer realized that from then on the code
> would be planted in a " $  jmp  $; " situation.  I intended flag to be
> cleared after an ADC interrupt.  ie set flag and wait for it to be cleared.
> Test code snippet and Makefile follow.

The compiler is allowed to assume that flag won't spontaneously change,
because you haven't told it otherwise. Either declare flag as volatile
(probably the simplest), or insert a memory barrier before checking its
value.

Cheers,
Daniel

--
Daniel Beer <[hidden email]> http://dlbeer.co.nz/
PGP: BA6E 0B26 1F89 246C E3F3  C910 1E58 C43A 160A 553B

------------------------------------------------------------------------------
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: while(flag)

Ian Chapman
On 11/08/15 17:25, Daniel Beer wrote:
Thanks guys I knew that I could count on you all for help. volatile,
that's new to me I'll look it up.  Kernighan and Ritchie say what you
all say but ANSI C says it's implementation dependent, as long as it
works.  Thanks Ian.

> On Sun, Nov 08, 2015 at 05:01:34PM -0500, Ian Chapman wrote:
>> Hi all,
>>        I'm having difficulty understanding this situation.
>> flag = 1;
>> while ( 0 != flag )
>> {
>> code;
>> }
>>    generates strange assembly code till I commented out
>> // flag = 1;
>> it looked to me like the optimizer realized that from then on the code
>> would be planted in a " $  jmp  $; " situation.  I intended flag to be
>> cleared after an ADC interrupt.  ie set flag and wait for it to be cleared.
>> Test code snippet and Makefile follow.
> The compiler is allowed to assume that flag won't spontaneously change,
> because you haven't told it otherwise. Either declare flag as volatile
> (probably the simplest), or insert a memory barrier before checking its
> value.
>
> Cheers,
> Daniel
>


------------------------------------------------------------------------------
Presto, an open source distributed SQL query engine for big data, initially
developed by Facebook, enables you to easily query your data on Hadoop in a
more interactive manner. Teradata is also now providing full enterprise
support for Presto. Download a free open source copy now.
http://pubads.g.doubleclick.net/gampad/clk?id=250295911&iu=/4140
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Reply | Threaded
Open this post in threaded view
|

Re: while(flag)

nick clifton
Hi Ian,

> Thanks guys I knew that I could count on you all for help. volatile,
> that's new to me I'll look it up.  Kernighan and Ritchie say what you
> all say but ANSI C says it's implementation dependent, as long as it
> works.

FYI: ANSI C is also out of date.  These days it is the ISO C99 standard
that you need to check.  In there you will find:

  6.7.3 Type qualifiers
  [...]
  6 An object that has volatile-qualified type may be modified in ways
    unknown to the implementation or have other unknown side effects.
    Therefore any expression referring to such an object shall be
    evaluated strictly according to the rules of the abstract machine,
    as described in 5.1.2.3. Furthermore, at every sequence point the
    value last stored in the object shall agree with that prescribed by
    the abstract machine, except as modified by the unknown factors
    mentioned previously. (114)  What constitutes an access to an object
    that has volatile-qualified type is implementation-defined.
  [...]
  114) A volatile declaration may be used to describe an object
    corresponding to a memory-mapped input/output port or an object
    accessed by an asynchronously interrupting function. Actions on
    objects so declared shall not be ‘‘optimized out’’ by an
    implementation or reordered except as permitted by the rules for
    evaluating expressions.

Cheers
   Nick


------------------------------------------------------------------------------
Presto, an open source distributed SQL query engine for big data, initially
developed by Facebook, enables you to easily query your data on Hadoop in a
more interactive manner. Teradata is also now providing full enterprise
support for Presto. Download a free open source copy now.
http://pubads.g.doubleclick.net/gampad/clk?id=250295911&iu=/4140
_______________________________________________
Mspgcc-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mspgcc-users