Help with register variables

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I'm trying to lock a register in AVR32 for use as a global variable with GNU compiler, similar to IAR __regvar command.

I tried:

register volatile U32 number asm("R15");

...and a few other modifications. The compiler error I get with this line is "invalid register name for 'number'". I tried to wade through the header files and find correct register names but failed. I also tried static addresses but they fail as well.

Please help and thanks for your replies.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

volatile <--> register?

:-D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also, R15 is the program counter so you can't use it as a general register.

Letting the smoke out since 1978

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would like to know which registers are ok to use in cases like this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What are you really trying to accomplish?

You must stay away from r7 and r9 - r12 at least. If you compile without frame pointer you can use the r7 register. r9 - r12 is used by functions, r9 - r12 are variables while r12 is the return value IIRC.

Hans-Christian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm hoping to speed up an application by having some key variables in a more accessible location.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not this way. Only keeping away from compilers work will speedup your progam ;-) If the performance-analysis of the GCC thinks that it issnt nesecary to keep a variable in a register, it is most likely that it issnt nesecary.

You may speed up some algorithms by using avr32-specific asm-instructions. but be carefull about this also this interrupts the GCCs optimazion process.. so using asm("min.. or asm("max.. instead of c-code is most likely slower. (not the instruction itstelf, but the code that depends on the result of the operation is complely unpredictable.. and optimizers love assumptions ;-) )

use the keyword register if you like, but do not force the compiler..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The grand idea behind all this is that accessing a global variable takes longer than accessing a register bound variable. The variable must be global and it is accessed very frequently.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

a load/store will add too much time? Sure you got your design in order? ;)

Hans-Christian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A simple incrementation of a 32-bit global variable ( variable++; ) converts to:

lddpc (details omitted)
ld.w
sub (subtract -1)
st.w
lddpc

Versus a register variable:

mov
sub
mov

You save 2 cycles everytime. But I might be nitpicking and the benefits of a register variable most likely disappear in a larger context. Thanks anyway. I'm an optimizer freak so I love this stuff. :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You forget, that a global vars are stored in mem, but if accesses, they are "cached" in registers.
So a singloe increment is slow, but a function that uses the variable often does not load the variable each time it is accessed (until you didnt add the volatile specifier).

Note: less instructions do not take less time. The compiler takes care of pipeline stalls and other stuff... this are things you can not optimize per hand..
So it could be that in O2-O3 the compiler mixes the code that the load/store is done during operations that would stall the pipeline.
All in all the code is most likely not slower.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for clarification. The volatile is a must since the variable is modified by an interrupt.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

outch. this costs mutch time than.
in this case if you like to have some speedup you can backup the variable in a function. if you do not depend on the value changed by the interrupt.

volatile unsigned int global;

void function()
{
    register unsigned int backup = global;
    for(int i = 0; i < BigNumber; i++)
    {
        //Use backup often AND fast :-)
    }
    //wait for interrupt
    while(backup == global);
}