здравствуйте.
вставлю свои 5 копеек.
1. FPU вычислительный блок который, как справедливо заметила Xenia, над данными типа флоат умеет делать арифмитические операци + немного необходимых ништяков. FPU за то то эти арифметические операции он сделал правильно с предсказуемым результатом.
2. в силу того сто косинусы логарифмы и тд это функции с аргументом типа флоат не раелизованы аппаратно в соответствующих библиотеках они реализованы как подпрограмки. стандарно это делается в виде быстросходящегося ряда. поэтому FPU понятия не имеет что за результат он получил в результате вычисленй и не может интепретировать результат логарифма - эта сущность выше по уровню. В частности результат NAN или INF это хороший правильный резульат - какие данные воткнули он вам для них выдал то что описывает стандарт IEEE764 .... он свое дело сделал и может честно отдыхать.
3. Вывод - в данной случае если вызывающая сторона не может контролировать входные данные то анализ резульата подпрограммы должна делать она сама - это забота libm (math.h) что и предполагается по стандарту на POSIX Standard C Library (https://ru.wikipedia.org/wiki/Errno.h). Код либы гарантирует что он в переменную errno запишет сотояние результата .... он свое дело сделал и может честно отдыхать. А его анализ ложится на вызывающую сторону. Если ты вызвал логарифм с кривыми входными данными - о чем ты можен по многим причина не знать и не ПРОВЕРИЛ СОСТОЯНИЕ РЕЗУЛЬТАТА то ты сам ДУРАК. одним словом FPU + libc/libm дает иструмент позволяющий выплыть из нештатной ситуации.
пример - возьмем реализацию из библиотеки NewLib в части libm : log
Код
#include "fdlibm.h"
#include <errno.h>
#ifdef __STDC__
float logf(float x) /* wrapper logf */
#else
float logf(x) /* wrapper logf */
float x;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_logf(x);
#else
float z;
struct exception exc;
z = __ieee754_logf(x);
if(_LIB_VERSION == _IEEE_ || isnan(x) || x > (float)0.0) return z;
#ifndef HUGE_VAL
#define HUGE_VAL inf
double inf = 0.0;
SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */
#endif
exc.name = "logf";
exc.err = 0;
exc.arg1 = exc.arg2 = (double)x;
if (_LIB_VERSION == _SVID_)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if(x==(float)0.0) {
/* logf(0) */
exc.type = SING;
if (_LIB_VERSION == _POSIX_)
errno = ERANGE;
else if (!matherr(&exc)) {
errno = ERANGE;
}
} else {
/* logf(x<0) */
exc.type = DOMAIN;
if (_LIB_VERSION == _POSIX_)
errno = EDOM;
else if (!matherr(&exc)) {
errno = EDOM;
}
exc.retval = nan("");
}
if (exc.err != 0)
errno = exc.err;
return (float)exc.retval;
#endif
}
здесь видно что если чтото пошло не так с точки зрения сути логарима то это отражается в глобальной для потока переменной errno для того чтоб пользователь не улетел в космос далнейшими вычислениями.....
4. это было введение о том как есть, а теперь мое предложение о том как сделать решение как хочется автору поста (естественно это приминительно для CORTEX-M4F или прочий ибо автор про его FPU затеял тему).
если нада дествительно эксепшен так что хачу-нимагу!! , ну например подчиненные программисты лесом посылают errno и лепят горбатого в своем коде то можно поступить следующим образом.
берем исходнички libm и во всех местах где errno присваиваются кода крывых состояний вызывать svc - бутет порожден эксепшен который приведет к исполненению обработчика прерывания - вот тут уже бойцы не смогут перепрыгнуть через окоп для танков и им прийдется прореагировать на ситуацию что чтото пошло не так.
5. а вообще, я считаю, нада всех кто не хочет стандарты изучать и применять в жизни, тек кто изобретает велосипЭд и прочих водителей луноходов пороть ремнем три раза в день и оставлять без ужина

надесь чем то помог.