Close

Two Additions In One Operation CTD -- Two Variables one register

A project log for limited-code hacks/ideas

When you're running out of code-space... sometimes yah's gots to hack. Here are some ideas.

eric-hertzEric Hertz 04/20/2023 at 04:480 Comments

A continuation of the last log:

Say you've got two 4bit variables:

One stores a state, the other stores a signed count from -7 to +7.

{Thumbtyping is hard...}

uint4_t state;

uint4_t state;
Int4_t count;

Switch{state}
{
   Case A:
     count++;
     Break;
   Case B:
     Count--;
...
}

Of course, int4_t is rare, if existent.

But merging them into one 8bit byte in register/RAM would mean a lot of boolean logic and shifts, right?

Maybe not! 

in fact, on an AVR [ATmega8515=old], it may be *fewer* operations than using separate 8bit variables, at least in some cases:

//state in low nibble,
// SIGNED count in high nibble
uint8_t stateAndCount;

Switch{stateAndCount & 0x0f}
{
   Case A:
     stateAndCount+=0x10;
     Break;
   Case B:
     stateAndCount-=0x10;
...
}

My big concern was incrementing and extracting the signed count.

[LOL, I'd forgotten that, in the situation I'm considering replacing with this, I was already masking the state-only variable with 0x0f in the switch statement... this thing is just falling together!]

Incrementing is a typical add-immediate, which I think is the same number of cycles as increment, since AVR instructions are always 16bits. [16 for inc/dec, or 8 for add-immediate + 8 for the immediate value=0x10]

That leaves extracting/using the signed count 

int32_t TotalCount += 
   ((int8_t)stateAndCount)>>4;

A Few concerns:

shift-right for signed integers, in C... Is it guaranteed 'arithmetic' rather than 'logical'?

[And what about negatives and rounding toward negative infinity](?]

Does the AVR have a single-instruction arithmetic-shift-right?

...

So. Thumbtyping is exhausting, I'll leave it to you to look up details, for now. But the short answer looks to be that there may even be cases where this takes *Fewer* instructions this way, than to have to load/store the two 4bit (8bit-stored) state/count variables in RAM.

...

I wonder what-all we can do that we aren't with 64 bits?!

Discussions