Tool/software: TI C/C++ Compiler
I have an interrupt routine that compares 2 function pointers and seeing unnecessary push/pop operations.
First example, the first pointer, RX_RECEIVE_IRQ, changes as a receive operation progresses.
The value u.rx.last_rx_cb is a function pointer of the same type that records the last observed interrupt handler.
If the interrupt handler differs from what was observed previously, then comms are active.
As can been seen, although u.rx.last_rx_cb is at a known compile time address, GCC copies the u pointer into a register and dereferences with an offset.
Second and more scary, RX_RECEIVE_IRQ is copied into a register despite being tagged volatile!
typedef void (*irq_cb)(); volatile irq_cb RX_RECEIVE_IRQ; union { struct {
int16_t data0;
int16_t data1; irq_cb last_rx_cb; } rx; } u; __attribute((interrupt)) void timeout(){ /* If the rx timeout has changed since last * time, then no timeout */ if(RX_RECEIVE_IRQ != u.rx.last_rx_cb){ u.rx.last_rx_cb = RX_RECEIVE_IRQ; return; } u.rx.last_rx_cb = RX_RECEIVE_IRQ; ... } 0000cc3e <rx_timeout>: cc3e: 0d 12 push r13 ; cc40: 0c 12 push r12 ; cc42: 1d 42 18 02 mov &0x0218,r13 ;0x0218 cc46: 3c 40 52 03 mov #850, r12 ;#0x0352 cc4a: 82 9d 56 03 cmp r13, &0x0356 ; cc4e: 06 20 jnz $+14 ;abs 0xcc5c cc50: 9c 42 18 02 mov &0x0218,4(r12) ;0x0218 cc54: 04 00 cc56: 3c 41 pop r12 ; cc58: 3d 41 pop r13 ; cc5a: 00 13 reti
The second code example is modified to move last_rx_cb out of the union/struct combo and into its own variable.
In this case, last_rx_cb is not copied into a register.
However, the former example should work without the extra push operation.
__attribute((interrupt)) void timeout(){ /* If the rx timeout has changed since last * time, then no timeout */ if(RX_RECEIVE_IRQ != last_rx_cb){ last_rx_cb = RX_RECEIVE_IRQ; return; } last_rx_cb = RX_RECEIVE_IRQ; ... } 0000cc3e <rx_timeout>: cc3e: 0c 12 push r12 ; cc40: 1c 42 18 02 mov &0x0218,r12 ;0x0218 cc44: 1c 92 9e 02 cmp &0x029e,r12 ;0x029e cc48: 05 20 jnz $+12 ;abs 0xcc54 cc4a: 92 42 18 02 mov &0x0218,&0x029e ;0x0218 cc4e: 9e 02 cc50: 3c 41 pop r12 ; cc52: 00 13 reti