Shop OBEX P1 Docs P2 Docs Learn Events
Possible compiler bug? — Parallax Forums

Possible compiler bug?

Jack BuffingtonJack Buffington Posts: 115
edited 2013-05-29 09:55 in Propeller 1
I originally posted this in the regular propeller forum since I thought that it had nothing to do with the C compiler but now I see that it does.

I have a .cogc file that is sharing a variable with HUB RAM, or at least I want it to be shared. In my main cog, I am declaring the variable like this:

volatile int iris = 1234;

The sum total of my .cogc file looks like this:
#include <propeller.h>extern unsigned int iris;


_NATIVE
void main ()
    {
    while(1)
        {
        iris = INA & 0b11;
        }
    }



The assembly listing that I get looks like this:
1                      .text   2                  .Ltext0
   3                      .balign    4
   4                      .global    _main
   5                      .global    _main_ret
   6                  _main
   7                  .LFB0
   8                      .file 1 "encoder.cogc"
   1:encoder.cogc  **** #include <propeller.h>
   2:encoder.cogc  **** extern unsigned int iris;
   3:encoder.cogc  **** 
   4:encoder.cogc  **** _NATIVE
   5:encoder.cogc  **** void main ()
   6:encoder.cogc  ****     {
   9                      .loc 1 6 0
  10                  .L2
   7:encoder.cogc  ****     while(1)
   8:encoder.cogc  ****         {
   9:encoder.cogc  ****         iris = INA & 0b11;
  11                      .loc 1 9 0 discriminator 1
  12 0000 0000BCA0         mov    r7, INA
  13 0004 00007C5C         jmp    #.L2
  14                  .LFE0
  42                  .Letext0
  43                      .file 2 "c:\\propgcc\\bin\\../lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/include/cog.h"



As you can see, "iris" is never written to HUB RAM nor is it AND'ed with 3. I have found that I can get it to compile if I set the compiler to "-O0 None" but then it produces some pretty inefficient code and even worse, it causes the rest of my program not to fit into HUB RAM. It seems like it shouldn't optimize out a write to HUB RAM ever. Does anyone have ideas about how to make this work without dropping to inline assembly code? I'm making it work with the addition of a waitcnt for now but I would rather not do that.


If you were following this on the other forum, the confusion that I was having there was that if I stick in a waitcnt command, the code compiles properly but only works if I give it enough time to run everything else. I had noticed that it ran if I put waitcnt in but didn't work if I left it out so I was assuming that it had something to do with how much delay I was giving it.

Comments

  • SRLMSRLM Posts: 5,045
    edited 2013-05-28 22:47
    What about this:
    extern [b]volatile[/b] int iris;
    
  • Jack BuffingtonJack Buffington Posts: 115
    edited 2013-05-28 22:55
    Ah. Works now. I thought that I only had to declare it as volatile when I declared it in my main C file. I just did a bit of reading about the volatile keyword. I have never run across that when working with C on any other processor. I get it now. Thanks!
  • pedwardpedward Posts: 1,642
    edited 2013-05-28 23:43
    Volatile basically says: "Hey compiler, don't try and do anything fancy, just do what I ask and don't get tricky with me".

    In short, it prevents the compiler from optimizing the variable away. The compiler can be a little too aggressive sometimes, and since your code didn't actually use the assignment, it gets optimized away.
  • SRLMSRLM Posts: 5,045
    edited 2013-05-28 23:55
    Ah. Works now. I thought that I only had to declare it as volatile when I declared it in my main C file. I just did a bit of reading about the volatile keyword. I have never run across that when working with C on any other processor. I get it now. Thanks!

    The problem is that you were declaring a different type with your original extern declaration, and that type wasn't volatile (and was unsigned instead of signed, but that's another issue). All the extern keyword does is prevent the immediate allocation of memory for a variable, leaving it unfulfilled until link time.
  • jac_goudsmitjac_goudsmit Posts: 418
    edited 2013-05-29 09:55
    SRLM wrote: »
    The problem is that you were declaring a different type with your original extern declaration, and that type wasn't volatile (and was unsigned instead of signed, but that's another issue). All the extern keyword does is prevent the immediate allocation of memory for a variable, leaving it unfulfilled until link time.

    What SRLM said.

    The best way to declare variables that are shared between multiple modules (even if one is a .cogc and another is a .c file) is to declare them in a separate file (say, iris.h) and include that file in all the modules where you use the variable.
    /* iris.h */
    volatile unsigned iris;
    

    Of course, you can (should!) remove the "extern volatile int iris" declaration from your .cogc module when you #include "iris.h".

    This will prevent conflicts e.g. between unsigned and signed integers, and other potential problems: whenever you want to change the declaration you only have to do it in one place: iris.h.

    The "extern" keyword isn't really necessary except in cases where you want your global variable initialized to something other than 0. In that case you'll have to do something like this:
    /* iris.h */
    
    #ifdef iris_DO_INIT
    #define iris_EXT
    #define iris_INIT(x) =x
    #else
    #define iris_EXT extern
    #define iris_INIT(x)
    #endif
    
    iris_EXT volatile unsigned iris iris_INIT(1234);
    iris_EXT volatile int some_other_variable iris_INIT(5678);
    
    /* encoder.cogc */
    
    #define iris_DO_INIT /* this causes all initializations to be expanded in iris.h */
    #include "iris.h"
    
    /* all other modules */
    
    #include "iris.h" /* all variables are declared extern */
    

    ===Jac
Sign In or Register to comment.