Tweeted twitter.com/#!/StackElectronix/status/525871063498899456
2 added 330 characters in body
source | link

I need to have programmable pause with precision as high as possible. To accomplish this I have the following GCC code:

void delay(unsigned char d){
  volatile unsigned char i=d;
  while(i>0) i--;
}

Which is compiled to:

1cc:    89 81           ldd r24, Y+1    ; 0x01
1ce:    81 50           subi    r24, 0x01   ; 1
1d0:    89 83           std Y+1, r24    ; 0x01
1d2:    89 81           ldd r24, Y+1    ; 0x01
1d4:    81 11           cpse    r24, r1
1d6:    fa cf           rjmp    .-12        ; 0x1cc <__vector_1+0x2c>

(I'm showing just the loop core code). This leads to the fact that the precision is 7 cycles which is not very acceptable. However I see that the compiler made his job not as fast as possible: If the i variable would be r24 register I will save 3 operations and the code would be almost twice as fast.

So how can I tell to the compiler that I want this variable to be in a register?

PS. I'd consider to pause with programmable number on nop's. But I can not imagine how this can be achieved. AVR has no instructions to branch to calculated address. As far as I know stack is not directly accessible in AVR (if it would I could push needed value to the stack and execute ret instruction to jump to the needed program address - it is also a tricky job but it would be at least considerable).

UPDATE After I changed volatile to register keyword (as was described in one of the answers) I've got the following code:

 14e:   81 50           subi    r24, 0x01   ; 1
 150:   f1 f7           brne    .-4         ; 0x14e <__vector_6+0x1c>

So I reduced the cycle from 7 to 2 cycles. Which is far better than I could expect.

I need to have programmable pause with precision as high as possible. To accomplish this I have the following GCC code:

void delay(unsigned char d){
  volatile unsigned char i=d;
  while(i>0) i--;
}

Which is compiled to:

1cc:    89 81           ldd r24, Y+1    ; 0x01
1ce:    81 50           subi    r24, 0x01   ; 1
1d0:    89 83           std Y+1, r24    ; 0x01
1d2:    89 81           ldd r24, Y+1    ; 0x01
1d4:    81 11           cpse    r24, r1
1d6:    fa cf           rjmp    .-12        ; 0x1cc <__vector_1+0x2c>

(I'm showing just the loop core code). This leads to the fact that the precision is 7 cycles which is not very acceptable. However I see that the compiler made his job not as fast as possible: If the i variable would be r24 register I will save 3 operations and the code would be almost twice as fast.

So how can I tell to the compiler that I want this variable to be in a register?

PS. I'd consider to pause with programmable number on nop's. But I can not imagine how this can be achieved. AVR has no instructions to branch to calculated address. As far as I know stack is not directly accessible in AVR (if it would I could push needed value to the stack and execute ret instruction to jump to the needed program address - it is also a tricky job but it would be at least considerable).

I need to have programmable pause with precision as high as possible. To accomplish this I have the following GCC code:

void delay(unsigned char d){
  volatile unsigned char i=d;
  while(i>0) i--;
}

Which is compiled to:

1cc:    89 81           ldd r24, Y+1    ; 0x01
1ce:    81 50           subi    r24, 0x01   ; 1
1d0:    89 83           std Y+1, r24    ; 0x01
1d2:    89 81           ldd r24, Y+1    ; 0x01
1d4:    81 11           cpse    r24, r1
1d6:    fa cf           rjmp    .-12        ; 0x1cc <__vector_1+0x2c>

(I'm showing just the loop core code). This leads to the fact that the precision is 7 cycles which is not very acceptable. However I see that the compiler made his job not as fast as possible: If the i variable would be r24 register I will save 3 operations and the code would be almost twice as fast.

So how can I tell to the compiler that I want this variable to be in a register?

PS. I'd consider to pause with programmable number on nop's. But I can not imagine how this can be achieved. AVR has no instructions to branch to calculated address. As far as I know stack is not directly accessible in AVR (if it would I could push needed value to the stack and execute ret instruction to jump to the needed program address - it is also a tricky job but it would be at least considerable).

UPDATE After I changed volatile to register keyword (as was described in one of the answers) I've got the following code:

 14e:   81 50           subi    r24, 0x01   ; 1
 150:   f1 f7           brne    .-4         ; 0x14e <__vector_6+0x1c>

So I reduced the cycle from 7 to 2 cycles. Which is far better than I could expect.

1
source | link

How can I bind a local variable to AVR's rXX register?

I need to have programmable pause with precision as high as possible. To accomplish this I have the following GCC code:

void delay(unsigned char d){
  volatile unsigned char i=d;
  while(i>0) i--;
}

Which is compiled to:

1cc:    89 81           ldd r24, Y+1    ; 0x01
1ce:    81 50           subi    r24, 0x01   ; 1
1d0:    89 83           std Y+1, r24    ; 0x01
1d2:    89 81           ldd r24, Y+1    ; 0x01
1d4:    81 11           cpse    r24, r1
1d6:    fa cf           rjmp    .-12        ; 0x1cc <__vector_1+0x2c>

(I'm showing just the loop core code). This leads to the fact that the precision is 7 cycles which is not very acceptable. However I see that the compiler made his job not as fast as possible: If the i variable would be r24 register I will save 3 operations and the code would be almost twice as fast.

So how can I tell to the compiler that I want this variable to be in a register?

PS. I'd consider to pause with programmable number on nop's. But I can not imagine how this can be achieved. AVR has no instructions to branch to calculated address. As far as I know stack is not directly accessible in AVR (if it would I could push needed value to the stack and execute ret instruction to jump to the needed program address - it is also a tricky job but it would be at least considerable).