Включение прерываний с плавающей запятой в Mac OS X Intel

В Linux функции FeenableException и FedisableException могут использоваться для управления генерацией прерываний SIGFPE для исключений с плавающей запятой. Как я могу сделать это на Mac OS X Intel?

Встроенный ассемблер для включения прерываний с плавающей запятой представлен в http://developer.apple.com/documentation/Performance/Conceptual/Mac_OSX_Numerics/Mac_OSX_Numerics.pdf, стр. 7–15, но только для сборки PowerPC.


person Geoffrey Irving    schedule 29.10.2008    source источник


Ответы (2)


Исключения для sse можно включить с помощью _MM_SET_EXCEPTION_MASK из xmmintrin.h. Например, чтобы включить недопустимые (nan) исключения, выполните

#include <xmmintrin.h>
...
_MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_INVALID);
person Geoffrey Irving    schedule 04.12.2008

В Mac OS X это довольно сложно. OS X по умолчанию использует модуль SSE для всей математики FP, а не модуль x87 FP. Модуль SSE не учитывает параметры прерывания, поэтому это означает, что в дополнение к разрешению прерываний вам необходимо убедиться, что весь ваш код скомпилирован, чтобы не использовать математику SSE.

Вы можете отключить математику, добавив «-mno-sse -mno-sse2 -mno-sse3» в свой CFLAGS. Как только вы это сделаете, вы можете использовать некоторую встроенную сборку для настройки ваших исключений FP, в основном с теми же флагами, что и в Linux.

short fpflags = 0x1332 // Default FP flags, change this however you want. 
asm("fnclex");
asm("fldcw _fpflags");

Одна загвоздка, которую вы можете обнаружить, заключается в том, что, поскольку OS X полностью построена с использованием sse, могут быть неотловленные ошибки. Я знаю, что раньше обработчик сигналов не возвращал правильные коды, но это было несколько лет назад, надеюсь, теперь это исправлено.

person Louis Gerbarg    schedule 31.10.2008
comment
Возможно, это было не так актуально в 2008 году, но стоит отметить, что 64-битный код использует модуль SSE, а не модуль x87 FP на всех платформах (не только OS X). - person Spock; 09.05.2014
comment
@Spock в Linux long double требует x87 FPU. Аналогично на Win64 с MinGW-W64. - person Ruslan; 17.02.2020