1980년에 발표된 **인텔 8087**은 8086 마이크로프로세서 제품군을 위한 최초의 x87 부동소수점 보조 프로세서이다.
8087의 용도는 더하기, 빼기, 곱하기, 나누기 및 제곱근과 같은 부동소수점 산술 계산 속도를 높이는 것이었다. 또한 지수, 대수 또는 삼각법 계산과 같은 초월 함수를 계산했으며 부동소수점 외에도 커다란 이진 및 십진 정수를 처리할 수 있었다. 특정 응용 프로그램에 따라 약 20%에서 500% 이상의 성능을 향상하였다. 8087은 약 2.4W를 사용하여 약 50,000 FLOPS를 수행할 수 있었다. 8087을 사용하면 산술 연산에서만 효과가 있었다. 예를 들어, 워드 프로세싱과 같은 응용 프로그램만 사용하는 컴퓨터는 추가적인 비용(약 $150)과 8087이 소비하는 전력에도 어떠한 이점도 얻지 못한다.

인텔 8087의 다이 (집적 회로)
8087은 당시의 첨단 IC였으며 그 시대 동안 제조 기술의 한계를 뛰어넘었다. 초기 수율은 매우 낮았다.
IBM이 IBM PC 마더보드에 보조 프로세서 소켓을 포함하면서 8087의 판매가 매우 증가했다. 칩 부족으로 인해 IBM은 실제로 시장에 출시 후 6개월 동아 8087을 PC용 옵션으로 제공하지 않았다. 8087의 개발로 부동소수점 산술을 위한 IEEE 754-1985 표준이 정립되었다. 이후 80186 (PC와 호환되는 시스템에 사용되지 않음), 80286, 80386 및 80386SX 프로세서용 x87 보조 프로세서가 나왔다. 80486부터 이후 인텔 x86 프로세서는 별도의 부동소수점용 보조 프로세서를 사용하지 않았다. 부동소수점 기능은 프로세서에 통합되어 제공되었다.

설계 및 개발
-------

인텔은 이전에 8231 산술 처리 장치 및 8232 부동소수점 프로세서를 제조했다. 이들을 8080 또는 유사한 프로세서와 함께 사용하도록 설계하였으며 8비트 데이터 버스를 사용했다. 이들은 프로그래밍 된 I/O 또는 DMA 컨트롤러를 통해 호스트 시스템과 연결되었다.

8087은 8086 칩 개발을 감독한 인텔의 엔지니어링 관리자인 빌 폴만(Bill Pohlman)에 의해 처음 고안되었다. 빌은 8086 칩이 아직 개발되지 않은 수학 계산용 칩을 지원할 수 있도록 조치를 했다.

1977년 폴만은 8087 수학 계산용 칩 설계를 진행했다. 브르스 라베넬(Bruce Ravenel)은 아키텍트로 임명되었으며 존 팔머(John Palmer)는 프로젝트의 공동-아키텍트이자 수학자로 고용되었다. 이 둘은 스택 아키텍처 CPU와 8개의 80비트 스택 레지스터, 다수의 계산을 위한 명령 세트를 포함하여 가장 긴 형식의 실수에 대해 64 비트의 가수와 16 비트의 지수로 혁신적인 디자인을 내놓았다. 이 설계는 수치 계산 및 수치 소프트웨어에서 알려진 몇 가지 뛰어난 문제를 해결했다. 64 비트 피연산자에 대한 반올림 오류 문제가 제거되었으며 모든 64비트 숫자에 대해 수치 모드 변환이 해결되었다. 팔머는 부동소수점에 대한 윌리엄 칸(William Kahan)의 글이 설계에 큰 영향을 미쳤다고 평가했다.

8087 설계는 처음에 적극적인 설계로 산타 클라라에서 멋진 평판을 받았다. 결국 인텔 이스라엘에서 설계를 하게 되었고 라피 네이브(Rafi Nave)는 칩 구현을 주도하도록 임명되었다. Palmer, Ravenel 및 Nave는 이 설계에 관한 특허를 받았다. Robert Koehler와 John Bayliss 또한 특정 비트 형태를 보인 일부 명령어가 보조 프로세서로 오프로드되는 기술에 관한 특허를 받았다.

8087은 45,000개의 트랜지스터가 있으며 3μm 공핍 부하(depletion-load) HMOS 회로로 제조되었다. 8086 또는 8088과 함께 작동하며 약 60개의 새로운 명령어를 도입했다. 대부분의 8087 어셈블리 니모닉은 FADD, FMUL, FCOM 등과 같이 F로 시작하므로 8086 명령어와 쉽게 구별 할 수 있다. 모든 8087 명령어에 대한 이진 인코딩은 비록 바이트의 상위 비트에 있긴 하지만 ASCII 문자 ESC와 동일한 10진수로 27인 비트 패턴 11011로 시작한다. 유사한 명령어 접두어를 "이스케이프 코드"라고도 한다. 이러한 보조 프로세서 명령어에 관해 인텔에서 할당한 명령어 니모닉은 "ESC"이다.

8086 또는 8088 CPU가 ESC 명령을 실행할 때 두 번째 바이트(ModR/M 바이트)가 메모리 피연산자를 지정한 경우 CPU는 버스 사이클을 실행하여 명령에 지정된 메모리 위치에서 한 단어를 (8086 주소 지정 모드를 사용하여) 읽는다. 그러나 읽기 피연산자를 CPU 레지스터에 저장하거나 그에 대한 작업을 수행하지 않는다. 8087은 버스를 관찰하고 8086과 동기화된 명령어들을 디코딩하여 자체 보조 프로세서 명령어로 인식한다. 메모리 피연산자가 있는 8087 명령어의 경우, 명령어가 피연산자가 읽도록 요청한 경우 8087은 주 CPU가 데이터 버스에서 읽은 데이터 워드를 가져온다. 읽을 피연산자가 한 단어보다 길면 8087은 주소 버스에서 주소를 복사한다. 그런 다음 CPU가 구동하는 데이터 읽기 주기가 완료된 후 8087은 즉시 DMA를 사용하여 버스를 제어하고 피연산자 자체의 추가 바이트를 전송한다. 메모리 피연산자가 있는 8087 명령어가 해당 피연산자를 쓰고자 할 경우, 8087은 데이터 버스에서 읽은 단어를 무시하고 단순히 주소를 복사한 다음 확장 피연산자의 끝을 읽는 것과 동일한 방식으로 DMA를 요청하고 전체 피연산자를 쓴다. 이러한 방식으로 메인 CPU는 버스 및 버스 타이밍에 대한 일반적인 제어를 유지한다. 반면, 8087은 8087이 버스를 취하여 피연산자를 내부 레지스터로(또는 에서) 읽거나 쓰는 데 걸리는 짧은 DMA 기간을 제외하고 보조 프로세서 명령 실행의 다른 모든 측면을 처리한다. 이 디자인의 결과로 8087은 메모리 또는 자체 레지스터에서 가져온 피연산자에서만 작동할 수 있고 8087과 8086 또는 8088사이의 데이터 교환은 RAM을 통해서만 이루어진다.

메인 CPU 프로그램은 8087이 명령어를 실행하는 동안 계속 실행된다. 메인 8086 또는 8088 CPU의 관점에서 볼 때 보조 프로세서 명령어는 opcode를 처리하거나 메모리 피연산자 주기 동안만 실행한다. 메모리 피연산자 주기는 피연산자가 없는 경우엔 2클록 주기가, 메모리 피연산자가 있는 경우에는 피연산자 워드의 두 번째 바이트를 전송하기 위해 8클럭주기 + EA 계산 시간[5 ~ 12클록)이 걸린다. 8088에서는 4클럭 주기 이상이 추가로 필요하다. 이 과정 후 CPU는 프로그램의 다음 명령을 실행하기 시작한다. 따라서 8087이 있는 시스템은 진정한 병렬 처리가 가능하여 메인 CPU의 정수 ALU에서 한 번의 작업을 수행하는 동시에 8087 보조 프로세서에서 부동소수점 연산을 수행할 수 있다. 8086 또는 8088은 명령 흐름 및 타이밍을 독점적으로 제어하고 8087의 내부 상태에 직접 액세스할 수 없으며 그리고 8087은 한 번에 하나의 명령만 실행할 수 있기 때문에 8086 또는 8088이 8087과 결합된 시스템용 프로그램은 8087이 다른 명령어를 처리하기 전에 처리중인 마지막 명령을 완료할 시간을 확보하도록 확실히 해야 했다. 이러한 목적으로 주 CPU의 WAIT 명령어가 제공되었으며, 대부분의 어셈블러는 대부분의 부동소수점 보조 프로세서 명령어 전에 WAIT 명령어를 암시적으로 선언했다. (프로그램이 타이밍에 민감한 8087 명령어 처리 요청 사이에 WAIT 대신 다른 수단으로 충분한 시간을 확실히 확보하여 8087이 이전 명령을 완료하기 전에 명령어를 받지 않는다면 8087 명령어 수행 전에 WAIT 명령어를 사용할 필요는 없다. WAIT를 사용하는 경우에 다음 8087 명령어가 바로 실행될 필요도 없다.) WAIT 명령은 8086/8088의 -TEST 입력 단자가 낮은 전압으로 인가될 때까지 기다린다. 그리고 이 핀은 8087을 사용하는 모든 시스템에서 8087의 BUSY 핀에 연결된다.(BUSY 핀이 비활성화(deassert)되면 때 TEST 신호 핀이 활성화(assert)됨.)

8086 및 8088의 명령어 프리패치 큐는 명령어를 패치하는 순간과는 항상 같은 것만은 않게 명령어가 실행될 때 시간을 정하기 때문에, 8087과 같은 보조 프로세서는 단순히 CPU 버스만을 지켜보고서 언제 8087를 위한 명령어가 다음번에 실행될 명령어가 될지를 결정할 수 없다. 8086 및 8088에는 2개의 큐 상태 신호가 보조 프로세서에 연결되어 프리패치 큐에서 명령어의 CPU 내부 실행 타이밍과 동기화한다. 8087은 자체적으로 동일한 프리패치 큐를 유지하며, 이 큐에서 실제로 실행되는 보조 프로세서 opcode를 읽는다. 8086 및 8088 프리패치 큐의 크기와 관리 알고리즘이 다르기 때문에 8087은 시스템이 재설정될 때 특정 CPU 버스 라인을 보고서 연결된 CPU 유형을 결정하고 8087은 그에 따라 내부 명령 큐를 조정한다. CPU와 보조 프로세서에 프리패치 큐 하드웨어의 중복은 전력 사용량과 총 다이 면적 면에서 비효율적이지만 보조 프로세서 인터페이스가 매우 적은 전용 IC 핀을 사용하게 해준다. 보조 프로세서 인터페이스를 정의한 8086이 출시될 당시 40개 이상의 핀을 가진 IC 패키지는 드물었고 비싸며 신호 전달 속도의 주요 제한 요소인 과도한 인출선 캐패시턴스와 같은 문제가 발생했다.

보조 프로세서 명령 코드(operation code, opcode)는 이스케이프 시퀀스로 시작하여 2바이트에 걸쳐 6bit로 인코딩된다.

```
 ┌───────────┬───────────┐
 │ 1101 1xxx │ mmxx xrrr │
 └───────────┴───────────┘
```

처음 3개의 "x" 비트는 부동소수점 연산 코드의 처음 3bit이다. 그런 다음 두 개의 "m"비트, 그 다음에 부동소수점 opcode의 후반 3비트, 3개의 "r" 비트가 뒤 따른다. "m"및 "r" 비트는 주소 지정 모드 정보를 지정한다.

특수 부동소수점 명령어를 사용하려면 응용 프로그램을 작성해야 한다 실행 중에 소프트웨어는 보조 프로세서를 감지하여 부동소수점 연산에 사용할 수 있다. 감지되지 않은 경우 소프트웨어에서 유사한 부동소수점 함수를 계산해야 하거나 보다 정확한 수치 호환성을 위해 전체 보조 프로세서를 소프트웨어에서 에뮬레이션할 수 있다.

### 레지스터

단순화한 8087 마이크로아키텍처
x87 제품군은 x86 프로세서의 주 레지스터와 같이 직접 주소 지정이 가능한 레지스터 세트를 사용하지 않는다. 대신에, x87 레지스터는 st0에서 st7까지의 8단계 딥 스택 구조를 형성하며, 여기서 st0은 최상위이다. x87 명령어는 이 스택에서 값을 넣거나 계산하거나 꺼낸다. 그러나 FADD, FMUL, FCMP 등과 같은 이항 연산은 암시적으로 최상위 st0 및 st1을 사용하거나 st0을 명시적 메모리 피연산자 또는 레지스터와 함께 사용할 수 있다. 따라서 st0 레지스터는 누산기 (즉, 결합된 대상 및 왼쪽 피연산자)로 사용될 수 있으며 FXCH stX (코드 D9C8–D9CFh)라는 명령을 사용하여 8개의 스택 레지스터 중 하나와 교환할 수도 있다. 따라서 x87 스택은 주소 지정이 가능한 7개의 레지스터와 누산기로 사용할 수 있다. 이것은 특히 슈퍼스칼라 x86 프로세서 (1993년 이후의 펜티엄)에 적용할 수 있으며, 이러한 교환 명령은 최적화하여 페널티를 0 클록까지 낮춘다.

### IEEE 부동소수점 표준

인텔은 8087을 설계할 때 향후 설계를 위한 부동소수점 형식을 표준화 하려고 했다. 역사적 관점에서 8087의 중요한 측면은 IEEE 754 부동소수점 표준의 기초가 되었다는 것이다. IEEE 754 표준이 1985년까지 완료되지 않았기 때문에 IEEE 754 표준의 모든 세부 사항을 8087에 구현하지 않았다. 그렇지만 80387에는 모든 것을 구현했다. 8087은 두 가지 기본 32/64비트 부동소수점 데이터 형식과 추가 확장 80비트 내부 임시 형식(메모리에 저장될 수 있음)을 제공하여 크고 복잡한 계산의 정확도를 향상시켰다. 이 외에도 8087은 80비트/18자리 묶음 BCD(18-digit packed BCD, 이진 코드 10진수) 형식과 16, 32 및 64비트 정수 데이터 형식을 제공했다.

|  |
| --- |
| **8087 데이터 형** |
| 79 | ... | 71 | ... | 67 | ... | 63 | ... | 50 | ... | 31 | ... | 22 | ... | 15 | ... | 00 | *(비트 위치)* |
| ± | 지수 | Fraction | 80-비트 확장정밀도 실수 |
|  | ± | 지수 | Fraction | 64-비트 배정밀도 실수 |
|  | ± | 지수 | Fraction | 32-비트 단정밀도 실수 |
|  |
| ± |  | BCD 정수 | 18-digit 10진수 정수 |
|  |
|  | ± | 정수 | 64-비트 이진 정수 |
|  | ± | 정수 | 32-비트 이진 정수 |
|  | ± | 정수 | 16-비트 이진 정수 |

### 무한

8087은 아핀 클로저(affine closure) 또는 프로젝티브 클로저(projective closure)로 무한을 처리한다. 상태 레지스터로 선택 가능하다. 아핀 클로저를 사용하면 + 및 - 무한대가 다른 값으로 처리된다. 프로젝티브 클로저를 사용하면 무한대를 매우 작거나 매우 큰 수의 부호 없는 표현으로 처리한다. 무한대를 처리하는 이 두 가지 방법을 IEEE 754 부동소수점 표준의 초안 버전에 통합하였다. 그러나 공식 IEEE 754-1985판에서 프로젝티브 클로저를 뺐다. 80287은 프로젝티브 클로저를 선택사항으로 유지했지만 80387 및 후속 부동소수점 프로세서(80187 포함)는 아핀 클로저만 지원했다.

### 모델 종류 및 제 2 공급자

인텔 8087 수치 보조 프로세서 핀아웃
인텔 8087 보조 프로세서는 세라믹 측면 납땜 DIP (CerDIP)와 밀폐 DIP (PDIP)의 두 가지 종류로 제작되었으며 다음 온도 범위에서 작동하도록 설계되었다.

* C와 D, QC, QD 접두사: 0 °C to +70 °C (상업용).
* LC와 LD, TC, TD 접두사: −40 °C to +85 °C (산업용).
* MC와 MD 접두사: −55 °C to +125 °C (군용).

8087의 모든 모델에는 40핀 DIP 패키지가 있으며 5볼트에서 작동하여 약 2.4와트를 소비한다. 최신 인텔 보조 프로세서와 달리 8087은 주 프로세서와 동일한 클럭 속도로 실행해야했다. 부품 번호의 접미사로 클록 속도를 식별한다.

8087 클록 속도| 모델 번호 | 동작속도 |
| --- | --- |
| 인텔 8087 | 5 MHz |
| 인텔 8087-1 | 10 MHz |
| 인텔 8087-2 | 8 MHz |
| 인텔 8087-3 | 4 MHz |
| 인텔 8087-6 | 6 MHz |

* 첫 5 MHz 인텔 C8087첫 5 MHz 인텔 C8087
* 첫 5 MHz 인텔 D8087첫 5 MHz 인텔 D8087
* 8 MHz 인텔 D8087-28 MHz 인텔 D8087-2
* 인텔 5 MHz C8087-3인텔 5 MHz C8087-3

이 제품은 AMD에서 AMD 8087로, 그리고 Cyrix에서 Cyrix 8087로 공급되었다. 소련에서 8087의 복제품 K1810WM87을 생산하였다.

### 후속 모델

8088 및 8086 프로세서가 이후 제품으로 대체된 것처럼 8087도 대체되었다. 다른 인텔 보조 프로세서는 80287, 80387 및 80187이다. 80486 이후부터 인텔 프로세서는 별도의 부동소수점 보조 프로세서를 사용하지 않았다. 80486DX에서 FPU를 비활성화한 80486SX를 제외하고 모든 메인 프로세서 다이에 포함하였다. 80487은 실제로 한 핀이 추가된 완전한 80486DX 칩이었다. 설치하면 80486SX CPU를 비활성화하였다. 80486DX, 펜티엄 및 이후 프로세서에는 CPU 코어에 부동소수점 기능을 포함하였다.