Я погонял компиляцию этого дела в разных режимах.
В том числе для ISR, в том числе с байтовой переменной состояния в ОЗУ и
Код
enum { IDLE = 0, DRAIN };
static uint8_t state = IDLE;
static void *state_addr[] PROGMEM = { &&idle, &&drain };
goto *(void*)pgm_read_word( &state_addr[state] );
что даёт бОльшую задержку на входе (но всё равно постоянную, не зависящую от ветви) и добавляет саму таблицу и код для зачитывания из неё, зато сокращает код и время для обновления состояния в ветвях, что на большом количестве состояний может дать выигрыш.
Довольно нормально получается.
Но реально не применяю :-), как-то не жмёт пока обычный switch()...