Wednesday 3 December 2014

When C++ templates outperform C

A colleague has recently faced me with a problem. He's writing some interesting stuff on an Arduino board which ships with an AVR microcontroller. On this sort of platform they provide header files with #define-s along the line of:

#define PORTA (*(volatile uint8_t*)0x1234)
#define PORTB (*(volatile uint8_t*)0x1235)

They're meant to be used to read and write devices ports with simple code like this:

    PORTA = 0; /* clear device register */

Also, many devices may be connected to the same port if they need just some bit instead of a whole word. So an LED can be seen as a device on bit 7 of PORTA and turned on with something like:

    PORTA |= 0x80;


His problem was something like: I'd like to have a C++ template to use as a type to declare my device on PORTx and bit N so I can just set and clear bits without worrying about bit-shifts, something like:

    device<PORTA, 7> led;
    led.set(); // or alternatively led |= 1

However, I know that 

    PORTA |= 0x80;

translates to a single assembly instruction to set just one bit along the line of

    sbi $0x1234, 7

I want that the template translates to exactly the same assembly code, so to not loose performances.