With this design, an interrupt can occur at any machine instruction between enabling interrupts until restoring the
PCON register from the shadow
PCON_shadow. Any such interrupt will clear the
IDL/PD bits in the
PCON_shadow variable, so the bits won't survive to the point when the background loop actually restores
PCON from the shadow. Thus, any interrupt that preempts the idle loop disables the idle mode, which accomplishes the goal of an interrupt-safe transition to idle mode.
M16C
The M16C 16-bit processor from Renesas supports the low-power wait mode, which is entered using a special WAIT instruction. However, the M16C datasheet is very specific that interrupts must be enabled before executing the WAIT instruction, so clearly the M16C doesn't support an atomic transition to the wait mode.8 The M16C datasheet contains no side notes similar to the AVR note about atomic execution of the SLEEP-SEI instruction pair, so I assume that the interrupt-disable instruction (FCLR I) is effective immediately.
Like the 8051, the only option for the M16C is to somehow disarm the transition to the wait mode in the ISRs, to prevent the background loop from entering the wait mode just after an interrupt. In contrast to the 8051, however, the M16C accomplishes the low-power mode transition using a special instruction, not through a write to a register, so the shadow register technique doesn't apply.
The idea of disarming the wait-mode transition from ISRs can be made to work in the M16C, but it requires replacing the WAIT instruction with something else (such as NOP or RTS). Yes, I am talking about self-modifying code, but I don't know of any other option for the M16C. Luckily, the M16C is a von Neumann architecture, so it can execute code from the RAM address space.