x87 — это подмножество инструкций архитектуры x86 , связанное с плавающей точкой . Оно возникло как расширение набора инструкций 8086 в виде дополнительных сопроцессоров с плавающей точкой , которые работают в тандеме с соответствующими процессорами x86. Эти микросхемы имеют имена, заканчивающиеся на «87». Это также известно как NPX (расширение числового процессора). Как и другие расширения базового набора инструкций, инструкции x87 не являются строго необходимыми для построения рабочих программ, но обеспечивают аппаратную и микрокодовую реализацию общих числовых задач, позволяя выполнять эти задачи намного быстрее, чем соответствующие процедуры машинного кода . Набор инструкций x87 включает инструкции для основных операций с плавающей точкой, таких как сложение, вычитание и сравнение, а также для более сложных числовых операций, таких как вычисление функции тангенса и ее обратной функции, например.
Большинство процессоров x86, начиная с Intel 80486, имели эти инструкции x87, реализованные в основном ЦП, но этот термин иногда все еще используется для обозначения этой части набора инструкций. До того, как инструкции x87 стали стандартом в ПК, компиляторам или программистам приходилось использовать довольно медленные библиотечные вызовы для выполнения операций с плавающей точкой, метод, который все еще распространен в (недорогих) встроенных системах .
Регистры x87 образуют восьмиуровневую глубокую нестрогую стековую структуру от ST(0) до ST(7) с регистрами, к которым может напрямую обращаться любой операнд, используя смещение относительно вершины, а также которые могут быть помещены в стек и извлечены из него. (Эту схему можно сравнить с тем, как стековый кадр может быть как помещён в стек/извлечён из стека, так и проиндексирован.)
Существуют инструкции для помещения, вычисления и извлечения значений на вершину этого стека; унарные операции (FSQRT, FPTAN и т. д.) затем неявно обращаются к самому верхнему ST(0), в то время как двоичные операции (FADD, FMUL, FCOM и т. д.) неявно обращаются к ST(0) и ST(1). Нестрогая модель стека также позволяет двоичным операциям использовать ST(0) вместе с прямым операндом памяти или с явно указанным регистром стека, ST( x ), в роли, аналогичной традиционному аккумулятору (комбинированный целевой и левый операнд). Это также может быть обращено на основе инструкция за инструкцией с ST(0) в качестве немодифицированного операнда и ST( x ) в качестве целевого . Кроме того, содержимое в ST(0) можно обменять с другим регистром стека с помощью инструкции, называемой FXCH ST( x ).
Эти свойства делают стек x87 пригодным для использования в качестве семи свободно адресуемых регистров плюс выделенный аккумулятор (или в качестве семи независимых аккумуляторов). Это особенно применимо к суперскалярным процессорам x86 (таким как Pentium 1993 года и более поздних), где эти инструкции обмена (коды D9C8..D9CF h ) оптимизированы до нулевого штрафа по часам за счет использования одного из целочисленных путей для FXCH ST( x ) параллельно с инструкцией FPU. Несмотря на то, что это естественно и удобно для программистов на языке ассемблера , некоторые авторы компиляторов обнаружили, что сложно создавать автоматические генераторы кода , которые эффективно планируют код x87. Такой интерфейс на основе стека потенциально может минимизировать необходимость сохранения переменных scratch в вызовах функций по сравнению с интерфейсом на основе регистров [1] (хотя исторически проблемы проектирования в реализации 8087 ограничивали этот потенциал. [2] [3] )
x87 обеспечивает двоичную арифметику с плавающей точкой одинарной точности, двойной точности и 80-битной двойной расширенной точности в соответствии со стандартом IEEE 754-1985 . По умолчанию все процессоры x87 используют 80-битную двойную расширенную точность внутри себя (чтобы обеспечить постоянную точность для многих вычислений, см. обоснование конструкции IEEE 754 ). Таким образом, заданная последовательность арифметических операций может вести себя немного иначе по сравнению со строгим FPU одинарной или двойной точности IEEE 754. [4] Поскольку это иногда может быть проблематичным для некоторых получисловых вычислений, написанных для предположения двойной точности для корректной работы, чтобы избежать таких проблем, x87 можно настроить с помощью специального регистра конфигурации/состояния для автоматического округления до одинарной или двойной точности после каждой операции. С появлением SSE2 инструкции x87 уже не так важны, как раньше, но по-прежнему важны как высокоточный скалярный блок для числовых вычислений, чувствительных к ошибкам округления и требующих точности мантиссы 64 бита и расширенного диапазона, доступных в 80-битном формате.
Количество тактов для примеров типичных инструкций FPU x87 (здесь показаны только версии регистр-регистр). [5]
Нотация A ... B (от минимума до максимума) охватывает вариации синхронизации, зависящие от состояния переходного конвейера и выбранной арифметической точности (32, 64 или 80 бит); она также включает вариации, вызванные числовыми случаями (такими как количество установленных битов, ноль и т. д.). Нотация L → H отображает значения, соответствующие самой низкой (L) и самой высокой (H) максимальным тактовым частотам, которые были доступны.
Компании, которые разработали или изготовили [a] блоки с плавающей точкой, совместимые с Intel 8087 или более поздними моделями, включают AMD ( 287 , 387 , 486DX , 5x86 , K5 , K6 , K7 , K8 ), Chips and Technologies ( сопроцессоры Super MATH ), Cyrix ( FasMath , Cx87SLC , Cx87DLC и т. д., 6x86 , Cyrix MII ), Fujitsu (ранний Pentium Mobile и т. д.), Harris Semiconductor (производил процессоры 80387 и 486DX ), IBM (различные конструкции 387 и 486 ), IDT ( WinChip , C3 , C7 , Nano и т. д.), IIT ( 2C87 , 3C87 и т. д.), LC Technology ( сопроцессоры Green MATH ), National Semiconductor ( Geode GX1 , Geode GXm и т. д.), NexGen ( Nx587 ), Rise Technology ( mP6 ), ST Microelectronics (производство 486DX , 5x86 и т. д.), Texas Instruments (производство процессоров 486DX и т. д.), Transmeta ( TM5600 и TM5800 ), ULSI ( сопроцессоры Math·Co ), VIA ( C3 , C7 и Nano и т. д.), Weitek ( 1067 , 1167 , 3167 и 4167 ) и Xtend ( 83S87SX-25 и другие сопроцессоры).
8087 был первым математическим сопроцессором для 16-разрядных процессоров , разработанным Intel . Он был разработан для работы в паре с микропроцессорами Intel 8088 или 8086. (Более ранние процессоры Intel 8231 и 8232 с плавающей точкой, продаваемые для использования с процессором i8080, на самом деле были лицензированными версиями процессоров AMD Am9511 и Am9512 FPU от 1977 и 1979 годов. [6] )
Хотя в оригинальном техническом описании 1982 года для ( основанных на NMOS ) 80188 и 80186, похоже, упоминаются конкретные математические сопроцессоры [7] , оба чипа фактически были сопряжены с 8087.
Однако в 1987 году для работы с обновленным процессором Intel 80C186 на базе КМОП компания Intel представила математический сопроцессор 80C187 [8] . Интерфейс 80C187 к основному процессору такой же, как у 8087, но его ядро по сути такое же, как у 80387SX, и, таким образом, полностью соответствует IEEE 754 и способно выполнять все дополнительные инструкции 80387. [9]
80287 ( i287 ) — математический сопроцессор для серии микропроцессоров Intel 80286. Модели Intel включали варианты с указанными верхними пределами частоты в диапазоне от 6 до 12 МГц. Версия NMOS была доступна на 6, 8 и 10 МГц. [ 10] Доступная версия 10 МГц числового сопроцессора Intel 80287-10 стоила 250 долларов США в партиях по 100 штук. [11] Эти коробочные версии 80287, 80287-8 и 80287-10 были доступны по цене 212, 326 и 374 долларов США соответственно. Была коробочная версия 80C287A, доступная по цене 457 долларов США. [12] Другие модели 287 с производительностью, подобной 387, — это Intel 80C287, созданная с использованием CHMOS III, и AMD 80EC287, изготовленная по технологии CMOS компании AMD , использующей только полностью статические затворы.
Позже последовал i80287XL с микроархитектурой 387SX с 287 выводами, [13] i80287XLT, специальная версия, предназначенная для ноутбуков, а также другие варианты. Он содержит внутренний множитель 3/2, так что материнские платы, которые запускали сопроцессор на 2/3 скорости ЦП, могли вместо этого запускать FPU на той же скорости ЦП. И 80287XL, и 80287XLT предлагали на 50% лучшую производительность, на 83% меньшее энергопотребление и дополнительные инструкции. [14]
80287 работает с микропроцессором 80386 и изначально был единственным сопроцессором, доступным для 80386, до появления 80387 в 1987 году. Однако 80387 является более предпочтительным из-за его более высокой производительности и больших возможностей его набора инструкций.
80387 ( 387 или i387 ) — первый сопроцессор Intel, полностью соответствующий стандарту IEEE 754-1985 . Выпущенный в 1987 году [15] , через два года после чипа 386, i387 отличается значительно улучшенной скоростью по сравнению с предыдущими сопроцессорами Intel 8087/80287 и улучшенными характеристиками тригонометрических функций. Он был доступен по цене 500 долларов США в партиях по 100 штук. [16] Вскоре после этого он стал доступен через Intel's Personal Computer Enhancement Operation по розничной цене 795 долларов США. [17] Версия с частотой 25 МГц была доступна в розничном канале по цене 1395 долларов США. [18] Математический сопроцессор Intel M387 соответствовал стандарту MIL-STD-883 Rev. C. Это устройство было протестировано, включая температурный цикл от -55 до 125 °C, герметичность и расширенный прожиг. Эта военная версия работает на частоте 16 МГц. Эта военная версия была доступна в 68-выводном PGA и в четырехъядерном плоском корпусе. Эта военная версия была доступна за 1155 долларов США в количестве 100 единиц для версии PGA. [19] Была доступна версия 387DX на 33 МГц, и она имела производительность 3,4 мегастоуна в секунду . [20] Следующие коробочные версии математического сопроцессора 387DX на 16, 20, 25 и 33 МГц были доступны по цене 570, 647, 814 и 994 долларов США соответственно. [21] Инструкции FPTAN и FPATAN процессоров 8087 и 80287 ограничены аргументом в диапазоне ±π/4 (±45°), а 8087 и 80287 не имеют прямых инструкций для функций SIN и COS. [22] [ необходима полная цитата ]
Без сопроцессора 386 обычно выполняет арифметику с плавающей точкой через (относительно медленные) программные процедуры, реализованные во время выполнения через программный обработчик исключений . Когда математический сопроцессор сопряжен с 386, сопроцессор выполняет арифметику с плавающей точкой на аппаратном уровне, возвращая результаты намного быстрее, чем (эмулирующий) вызов программной библиотеки.
i387 совместим только со стандартным чипом i386, который имеет 32-битную шину процессора. Более поздний удешевленный i386SX, который имеет более узкую 16-битную шину данных , не может взаимодействовать с 32-битной шиной i387. Для i386SX требуется собственный сопроцессор, 80387SX , который совместим с более узкой 16-битной шиной данных SX. Intel выпустила маломощную версию сопроцессора 387SX. [23]
Был Intel387 SL Mobile Math Coprocessor, который имел функции управления питанием, которые могли работать без значительного сокращения срока службы батареи. Есть два режима энергосбережения. Первый содержит режим «стоп-такта», который автоматически отключает математический сопроцессор, когда он не нужен. Этот режим потребляет около 25 микроампер. Второй режим работает автоматически, когда пользователь запускает приложение, требующее, чтобы сопроцессор выполнял инструкцию. Этот режим обычно потребляет на 30 процентов меньше энергии батареи (около 100 мА), чем обычный Intel387 SX Math Coprocessor. Он переходит в «режим ожидания», когда он не выполняет инструкцию, до менее 4 мА, что на 96 процентов меньше мощности по сравнению с активным режимом. Он будет работать в диапазоне от 16 до 25 МГц и не требует перенастройки BIOS или оборудования. Он был доступен за 189 долларов США. [24]
i487SX (P23N) был продан как сопроцессор с плавающей точкой для машин Intel i486SX . Фактически он содержал полноценную реализацию i486DX . При установке в систему i486SX i487 отключал основной ЦП и брал на себя все операции ЦП. i487 принимал меры для обнаружения присутствия i486SX и не функционировал без оригинального ЦП. [25] [26] [ проверка не удалась ]
Nx587 был последним FPU для x86, который производился отдельно от центрального процессора (в данном случае Nx586 от NexGen ) .