Set pin to value of variable: bit field vs __builtin_avr_insert_bits

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

I've tried two methods of setting a pin to the value of a variable. Am I right to assume that this:

 

struct bits {
  uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
} __attribute__((__packed__));
#define SBIT(port,pin) ((volatile struct bits*)&port)->b##pin

#define PIN     SBIT(PORTD, 3)

uint8_t test;

int main()
{
  PIN = test;
}

which results in this:

 

        lds r24,test
        sbrc r24,0
        sbi 0xb,3
        sbrs r24,0
        cbi 0xb,3

 

 

is 1 cycle faster than this:

 

#include <stdint.h>
#include <avr/io.h>

volatile uint8_t test;

int main()
{
  PORTD = __builtin_avr_insert_bits(0xffff0fff, test, PORTD);
}

 

which results in this:

 

        in r24,0xb
        lds r25,test
        bst r25,0
        bld r24,3
        out 0xb,r24

 

and both are several cycles faster than the naive? more portable? "if (test) PORTD |= 1 << 3; else PORTD &= ~(1 << 3)" which result in this?

 

	lds r24,test
	tst r24
	breq .L2
	sbi 0xb,3
.L3:
	ldi r25,0
	ldi r24,0
/* epilogue start */
	ret
.L2:
	cbi 0xb,3
	rjmp .L3

 

It's not that 1 cycle is going to change anything in my projects, but I'm curious. I'm trying to wrap my head around the sbrc/sbi/sbrs/cbi combo; I suppose since one of sbrc/sbrs is always true and the other false the whole sequence will take 3 cycles, right?

 

(edit) Wait, I think it's four cycles like the code generated by __builtin_avr_insert_bits, since the sbrX that fails takes 2 cycles PLUS the next instruction, not including it. So sbrc/sbi/sbrs/cbi is either 1+0+2+1 or 2+1+1+0 = 4.

 

 

Last Edited: Fri. Sep 14, 2018 - 07:59 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you are in any doubt about the cycles then step the code in the simulator.

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

Watch out: Your code examples are not identical; consider what happens when test=2; (Or indeed any non-zero value where bit-0 is clear)

 

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

clawson wrote:

If you are in any doubt about the cycles then step the code in the simulator.

I tried to, but I'm going to need a few more days to understand simavr and how to use it to count cycles :). I'm new to avr.

 

N.Winterbottom wrote:

Watch out: Your code examples are not identical; consider what happens when test=2; (Or indeed any non-zero value where bit-0 is clear)

I know; the third snippet works for any value of "test" whereas the first two only work for test=0 and test=1. But let's say I control the test variable and I know it's either 0 or 1. It seems obvious the first two are more efficient (speed- and space-wise) but I don't know which is better. I suppose the first, since it only uses one register and (I think) they both take the same number of cycles.

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

vaar wrote:
I tried to, but I'm going to need a few more days to understand simavr and how to use it to count cycles
I'm talking about the sim in AS7 - that's the one that does cycle counting.

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

N.Winterbottom wrote:

Watch out: Your code examples are not identical; consider what happens when test=2; (Or indeed any non-zero value where bit-0 is clear)

 

I've gone through OP's exercise a number of times over the years.  It seems to often come up in AVR apps -- a number of outputs to set each pass after closing the app loop.  While ideally the bank of outputs can  be gathered into complete ports, that is often not possible/practical, especially on a model with "broken up" ports such as Mega88 family.

 

And indeed the AVR instruction set doesn't lend itself that well to "copy a bit value to I/O".

 

In the end, I often end up with the brute-force if/else.  That isn't bad if the "test" is explicitly, or implicitly by the compiler, in a register for repetitive skip instructions.

 

I think there is a thread or two already where this is explored.  I thought the C conditional-expression might be a good choice, but it turns out not to be -- at least with my toolchain.

https://www.avrfreaks.net/forum/...

https://www.avrfreaks.net/forum/...

https://www.avrfreaks.net/commen... leads to https://www.avrfreaks.net/commen... [see entire thread] and https://www.avrfreaks.net/forum/...

 

 

 

 

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.

Last Edited: Fri. Sep 14, 2018 - 02:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

I'm talking about the sim in AS7 - that's the one that does cycle counting.

Then it's hopeless since I don't have windows...

 

theusch wrote:
I think there is a thread or two already where this is explored.  I thought the C conditional-expression might be a good choice, but it turns out not to be -- at least with my toolchain.

https://www.avrfreaks.net/forum/...

https://www.avrfreaks.net/forum/...

https://www.avrfreaks.net/commen... leads to https://www.avrfreaks.net/commen... [see entire thread] and https://www.avrfreaks.net/forum/...

Interesting threads, thanks. Also, by reading your post in the second to last one I realized I was wrong about sbrc/sbi/sbrs/cbi: sbi and cbi are 2 cycles, so it would take 2 + 2 + 1 + 0 or 1 + 0 + 2 + 2 = 5 cycles. That would make the in/bst/bld/out generated by __builtin_avr_insert_bits faster (1 + 1 + 1 + 1), if more register hungry.

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

At present AVR are principally based on Windows development tools so until the switch to multi platform MPLAB you probably want to run Windows in a VM to get access to AS7.

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

clawson wrote:
At present AVR are principally based on Windows development tools so until the switch to multi platform MPLAB you probably want to run Windows in a VM to get access to AS7.
Some of us do just fine without Windows already  ;-)

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Believe meyou are really missing out without access to their simulator. There's nothing available for Linux to equal it.

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

clawson wrote:

Believe meyou are really missing out without access to their simulator. There's nothing available for Linux to equal it.

True, simulavr isn't as sophisticated, and the device support is not 100%, but when I've needed simulation (which is rare), it has been plenty good. I'm definitely not missing out on anything I value.

That said, I recognise that I'm in the minority... Not because I'm that much better than the average developer (rather the opposite I expect...), but because a scarce few of my needs are not met by a world without Microsoft, and the giant shit sandwich that comes lashed to it is not, for me, worth the gains it offers.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

The cycle counter in AS7 is worth the entrance price alone ;-)

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

Right, but simulavr can count cycles, too, so that's not much of an incentive for me...
It's ok, I hold no malice toward those who feed the M$ beast ;-)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

If you want, https://github.com/avrsimulator/gdbproxy provides a gdb-server around our models (the dfps contain 64-bit Linux and win32 models for most AVRs)

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)