Never mind.

Ok, this ended up being much noise about nothing

This doesn't surprise me, I've seen this before from compilers. They don't do interrupts efficiently, but rather play it safe.Problem is it's probably difficult to trace register usage thru function calls made from the ISR. This is the classic trade-off, suffer with poor C generated code, or spend the time to do it yourself in ASM.

For me, I'd rather use an 85 with 8 KB for a few cents more . This is what I've lived through from the early 80's - all that byte tweaking went away with cheap memory, more powerful processors. Now our embedded control panel displays are Win7/10 based, using C#/.NET, where in the 80's we were working with Z-80's, 68000's, 8086's in C/ASM.

Realistically if you want to keep using 25's with Bistro, TK did a great job to fit in what she did in 2 KB, but to do more, getting into some inline ASM or modular use of ASM may help big time. I've worked on many embedded mixed C/ASM projects in the past.

Compilers have generally come a long way for efficiency, but they took a big hit, even gotten considerably worse when all the development got moved offshore - I've seen it, lived with it. So what we got now is certainly a generation or 2 ahead of the first offshore iterations, so getting better once again. Not familiar with the history of the Atmel tools as much, but seen it with other processors and associated development tools. There's some great tools out there, but can be costly too.

Oopsie, oh well...

Sorry for wasting your time :FACEPALM:. The naked thing IS an issue and you can save space there if you know what you're doing, but the rest was just me messing up. I had optimization turned off. Nothing to see here.

Anyway, yeah, I'm still going to implement the interrupt completely in inline asm because I jsut don't trust the compiler not to do something silly later, and in a naked interrupt, if that happened, or just if someone else uses funny optimizations, that would break things, so might as well avoid it.

Here's the whole naked interrupt in the end and it does save some bytes, but does require those funny defines (to be put somewhere else)
And actually PORTB is ALWAYS 0x18 on every AVR so I may just hard code that one.

#define Q(x) #x
#define Quote(x) Q(x)
#define PORTB_address 0x18
#ifdef PWM4_LVL
__asm__ __volatile__ (
"sbi " Quote(PORTB_address) " , " Quote(PWM4_PIN) " \n\t"
"reti" "\n\t"

But under normal conditions the usual idioms for pin setting work fine with optimization not disabled.