WinAVR seems to produce a lot of useless code, e.g. for following C method
ISR(INT0_vect) {
TCCR1B = 0x09;
}
it produces (-Os
)
PUSH R1 Push register on stack
PUSH R0 Push register on stack
IN R0,0x3F In from I/O location
PUSH R0 Push register on stack
CLR R1 Clear Register
PUSH R24 Push register on stack
LDI R24,0x09 Load immediate
STS 0x0081,R24 Store direct to data space
POP R24 Pop register from stack
POP R0 Pop register from stack
OUT 0x3F,R0 Out to I/O location
POP R0 Pop register from stack
POP R1 Pop register from stack
RETI Interrupt return
although
PUSH R0 Push register on stack
LDI R0,0x09 Load immediate
STS 0x0081,R0 Store direct to data space
POP R0 Pop register from stack
RETI Interrupt return
should be sufficient. Because these extra commands take time, my question: how to tell the compiler to produce only the required code? Or is there a tool which can optimize the byte code directly?
UPDATE: I've tried
ISR(INT0_vect, ISR_NAKED) {
asm volatile(
"push r0 \n\t"
"ldi r0, %[value] \n\t"
"sts %[ioReg], r0 \n\t"
"pop r0 \n\t"
"reti \n\t"
: // output
: // input
[ioReg] "M" (_SFR_IO_ADDR(TCCR1B)),
[value] "M" (0 << ICNC1
| 0 << ICES1
| 0 << WGM13
| 1 << WGM12
| 0 << CS12
| 0 << CS11
| 1 << CS10)
);
}
but the compiler complains:
c:\temp/ccjBxDFz.s: Assembler messages:
c:\temp/ccjBxDFz.s:30: Error: register number above 15 required
I've read a lot of AVR inline assembler documentation/tutorials, but can't get it to compile.