sbi / cbi optimization?

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

Shouldn't all the SFR in iom128.h header file optimize to sbi and cbi when using bitwise operators?
I've tried all the optimization settings but none caused the SFR's above address 0x1F to be accessed using sbi or cbi. If I use the I/O address of the SFR's instead of the values defined in iom128.h for address's above 0x1F then it will use sbi or cbi. Conversely, the SFR's up to 0x1F(EEARH) need to be accessed with the iom128.h file that defines them using the "data space" address (plus 0x20). I'm using WinAVR-20071221.

#include 
#include 
#define _nop_() __asm__("nop" ::)

int main (void)
{    
    (*(volatile uint8_t *)(0X3f)) |=  _BV(0);//- SREG io
    _nop_();
    
    SREG |= _BV(SREG_T);    //- 0x3F + 0x20
    _nop_();

    EEARH &= ~_BV(2);       //- 0x1F + 0x20  <--- cbi
    _nop_(); 
  
    SPDR |= _BV(1);         //- 0x0F + 0x20
    _nop_();  
    
    (*(volatile uint8_t *)(0X0F)) |=  _BV(0);//- SPDR io
  
    while (1)_nop_();
}
000000ce 
: ce: f8 9a sbi 0x1f, 0 ; 31 d0: 00 00 nop d2: 8f b7 in r24, 0x3f ; 63 d4: 80 64 ori r24, 0x40 ; 64 d6: 8f bf out 0x3f, r24 ; 63 d8: 00 00 nop da: fa 98 cbi 0x1f, 2 ; 31 dc: 00 00 nop de: 79 9a sbi 0x0f, 1 ; 15 e0: 00 00 nop e2: 80 91 0f 00 lds r24, 0x000F e6: 81 60 ori r24, 0x01 ; 1 e8: 80 93 0f 00 sts 0x000F, r24 ec: 00 00 nop ee: fe cf rjmp .-4 ; 0xec
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you look at the end of the instruction set table in the datasheet, you'll find a note like this one:

Quote:
The CBI and SBI instructions work with registers $00 to $1F only.

Regards
Sebastian

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

And if you want to know why, just look at the 16-bit opcode for the these instructions,

for example-
SBI A,b
SBI -> 1001 1010 AAAA Abbb

there is only 5 bits for A, which means it can only contain 0x00-0x1F.

If you don't already have the instruction set pdf from Atmel, get it. Along with the datasheet pdf, I have this pdf always open and I refer to it all the time (whether using C or not).

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

Also note that IN/OUT have just 6 bits for AAAAAA which means they can only operate on IO space addresses 0x00 to 0x3F

So (if just a single bit change) the compiler will use CBI/SBI on 0x00..0x1F and IN/OUT (with AND/OR) if more bits change

For 0x20..x03F it will use IN/OUT

For 0x40.. it will use LDS/STS with an intervening AND/OR

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

SPDR is in the range of 0x00-0x1f, but the optimization is not happening when casting an address rather than using the definition from the header file.

Try _SFR_IO8(0x0f) instead. This macro puts the offset in correctly.

SREG |= _BV(SREG_T); 
    in   r24, 0x3f
    ori   r24, 0x40
    out   0x3f, r24

In this one, the compiler is missing an optimization. SREG (0x3f) is out of range of sbi/cbi, but there are special opcodes to manipulate the bits of SREG that are not being used.

Regards,
Steve A.

The Board helps those that help themselves.

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

Quote:

In this one, the compiler is missing an optimization. SREG (0x3f) is out of range of sbi/cbi, but there are special opcodes to manipulate the bits of SREG that are not being used.

Well, that was my thought, but perhaps (or obviously?) not politially correct. If one is going to use _BV and _nop_ and adds a statement such as "#define _nop_() __asm__("nop" ::) " then why not just add someting like "#define _set_() __asm__("set" ::) "?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

> In this one, the compiler is missing an optimization.

Nobody has taught it about optimizing direct SREG manipulations.
Except for the T flag, it usually doesn't make sense to even
try it anyway.

I'd argue that using the T flag within C code has only marginal value
(how many bytes of code do you really save that way, compared to a normal
boolean or bitfield variable?), so for those few people who want to use the
T flag, it's probably fine to resort to inline asm for those couple of
instructions.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

to use cbi and sbi which header file one should use if one is using avr studio 4

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

Quote:
to use cbi and sbi which header file one should use if one is using avr studio 4

Are you talking about programming in GCC? If so you don't need to do anything special. As long as optimisation is switched on the compiler will use CBI/SBI when it can.