AnsweredAssumed Answered

A better workaround for the STM8 division bug

Question asked by Philipp Krause on Aug 2, 2015
The STM8 has a bug inits division implementation relating to the use of the undocumented bit 6 of the condition code register (see "Unexpected DIV/DIVW instruction result in ISR" in various STM8 errata notes).

ST recommends to add the following code to clear the undocumented bit as a workaround at the beginning of interrupt handlers that might contain a division:

push cc
pop a
and a, #0xbf
push a
pop cc

This workaround increases the cost of interrupt handlers by 6 bytes and 7 cycles (5 from the instructionsthemselves, 2 from pipeline stalls). Compilers therefore omit the workaround for interrupt handlers that contain neither divisions nor function calls. SDCC even does some interprocedural analysis following the function calls.

However, I found the situation still somewhat unsatisfying, and started looking for a cheaper workaround, running lots of tests on STM8S and STM8L hardware. This is what I found:

clr a
div x, a

The div clears the undocumented bit. The clr ensures that we do a divison by zero, since divisions by zero are cheap in terms of cycle count on the STM8. This workaround costs just 2 bytes and 2-3 cycles.

Starting with version 3.5.2 #9290, SDCC uses this cheaper workaround instead of the one originally recommended by ST.