Прерывания и особые ситуации: Условия генерации и осбенности обработки SIMD-исключений

Печать
Программирование - Архитектура и система команд микропроцессоров x86

 

В большинстве случаев поведение процессора при обработке SIMD-исключений на 100% совпадает с рекомендациями стандарта ANSI/IEEE 754 (стандарт для двоичной арифметики с плавающей точкой).

Некоторые отличия от стандарта проявляются при инициализированном режиме "сдвига к нулю" (Flush to Zero) и для команд, которые по стандарту, когда исключения не замаскированы, должны генерировать какой-либо результат перед передачей управления в обработчик исключений. Многие из таких команд оставляют все операнды неизменными и не помещают никаких результатов ни в регистры ни в память, обработчик исключения может сам сгенерировать необходимое значение перед продолжением вычислений.

 

Недействительная операция (#I)

Исключение "недействительная операция" индицируется флагом MXCSR.IE (бит 0). Оно генерируется в самых различных случаях, когда команды используют некорректные или специальные операнды. Если исключение не замаскировано (MXCSR.IM = 0), то вызывается обработчик исключений, и операнды остаются неизмененными. Если же исключение замаскировано, то обычно в качестве результата операции возвращается специальное значение — неопределенность в формате операнда-назначения.

 

Денормализованный операнд (#D)

Исключение "денормализованный операнд" индицируется флагом MXCSR.DE (бит 1). Оно генерируется при попытке использования денормализованных операндов в арифметических командах ADDPS, SUBPS, MULPS, DIVPS, SQRTPS, MAXPS, MINPS, CMPPS, ADDSS, SUBSS, MULSS, DIVSS, SQRTSS, MAXSS, MINSS, CMPSS, COMISS, UCOMISS.

Если SIMD-исключение "денормализованный операнд" не замаскировано (MXCSR.DM = 0), то при встрече денормализованного операнда устанавливается флаг MXCSR.DE и происходит вызов обработчика исключений (операнды при этом не изменяются).

Если SIMD-исключение "денормализованный операнд" замаскировано (MXCSR.DM = 1), то возвращается округленный результат (но только в том случае, когда этот результат не вызывает других незамаскированных исключений).

 

Деление на нуль (#Z)

Исключение "деление на нуль" индицируется флагом MXCSR.ZE (бит 2). Оно возникает при делении ненулевого операнда на нуль. Это возможно в командах DIVPS, DIVSS.

Если исключение не замаскировано (MXCSR.ZM = 0), то вызывается обработчик исключения, а исходные операнды остаются неизменными.

Если же исключение замаскировано (MXCSR.ZM = 1), то возвращается бесконечность со знаком равным исключающему ИЛИ (XOR) знаков операндов.

 

Переполнение (#O)  

Исключение "переполнение" индицируется флагом MXCSR.OE (бит 3). Оно генерируется, если результат операции превышает максимально допустимое значение для положительных чисел или минимально допустимое для отрицательных. Это может происходить в командах ADDPS, SUBPS, MULPS, DIVPS, ADDSS, SUBSS, MULSS, DIVSS.

Если SIMD-исключение "переполнение" замаскировано (MXCSR.OM = 1), то при встрече переполнения процессор устанавливает флаги MXCSR.OE, MXCSR.PE и возвращается одно из значений по таблице 3.9.

 

Таблица 3.9. Значения, возвращаемые, когда SIMD-исключение "переполнение" замаскировано

Значения, возвращаемые, когда SIMD-исключение

 

Если SIMD-исключение "переполнение" не замаскировано (MXCSR.OM = 0), истинный результат вычисляется без ограничения экспоненты (т.е. вычисления внутри процессора идут со значениями иной разрядности, чем это предусмотрено для результата), затем округляется и делится на 2192. Далее процессор устанавливает флаг MXCSR.OE и, в зависимости от полученного результата, флаг исключения точности MXCSR.PE и передает управление обработчику исключений.

 

Антипереполнение (#U)

Исключение "антипереполнение" индицируется флагом MXCSR.UE (бит 4). Оно может быть вызвано командами ADDPS, SUBPS, MULPS, DIVPS, ADDSS, SUBSS, MULSS, DIVSS, которые выдают очень маленький результат, который из-за своей малости не может быть представлен в формате операнда-назначения без потери точности.

Если SIMD-исключение "антипереполнение" замаскировано (MXCSR.UM = 1), то возвращается денормализованный, нормализованный или нулевой результат, также может генерироваться исключение #P.

Если SIMD-исключение "антипереполнение" не замаскировано (MXCSR.UM = 0), то истинный результат вычисляется без ограничения экспоненты (т.е. вычисления внутри процессора идут со значениями иной разрядности, чем это предусмотрено для результата), затем округляется и умножается на 2192. Далее процессор устанавливает флаг MXCSR.UE и, в зависимости от полученного результата, флаг исключения точности MXCSR.PE и передает управление обработчику исключений.

 

Неточный результат (#P)

Исключение "неточный результат" индицируется флагом MXCSR.PE (бит 5). Оно возникает, если результат операции не может быть точно представлен в формате операнда-назначения в командах ADDPS, SUBPS, MULPS, DIVPS, SQRTPS, CVTPI2PS, CVTPS2PI, ADDSS, SUBSS, MULSS, DIVSS, SQRTSS, CVTSI2SS, CVTSS2SI, CVTTSS2SI.

При обнаружении неточного результата, который не вызывает генерации SIMD-исключений "переполнение и "антипереполнение", независимо от того, замаскировано (MXCSR.PM = 1) или не замаскировано (MXCSR.PM = 0) SIMD-исключение "неточный результат", процессор устанавливает флаг MXCSR.PE и возвращает округленный результат. Метод округления задается текущим значением поля MXCSR.RC.

Когда SIMD-исключение "неточный результат" происходит вместе с замаскированным SIMD-исключением "переполнение" или "антипереполнение", то процессор устанавливает флаги MXCSR.PE и, соответственно, MXCSR.OE или MXCSR.UE, а затем возвращает результат так, как это описано для этих исключений, далее управление передается в обработчик исключений, если MXCSR.PM = 0.