인텔 8087의 부동소수점 덧셈·뺄셈 마이크로코드 분석
원제 The Intel 8087 chip: floating-point addition and subtraction
106 포인트댓글 34
Key Point
1980년대 칩 설계의 정수 가산기·비트 시프터 같은 전용 회로와 마이크로코드 최적화가 어떻게 부동소수점 연산 속도를 100배 향상시켰는지 보여주며, 현대 CPU의 부동소수점 처리 기초를 이해할 수 있다.
핵심 요약
- 1980년 인텔이 IBM PC 시스템의 부동소수점 연산을 약 100배 빠르게 만든 8087 칩을 출시했으며, 이 글은 칩을 직접 분해해 덧셈과 뺄셈 구현 방식을 설명한다.
- 8087은 부동소수점 수를 '부호 × 유효숫자 × 2^지수' 형태로 표현하며, 덧셈과 뺄셈을 위해 먼저 두 수의 소수점을 정렬한 후 정수 연산을 수행하고 결과를 정규화해야 한다.
- 칩 내부에는 80비트 임시 실수 형식(15비트 지수, 64비트 유효숫자)을 저장하는 8개의 스택 레지스터와, 덧셈·뺄셈·곱셈·나눗셈에 사용되는 69비트 정수 가산기, 임의 비트 수로 빠르게 시프트 가능한 비트 시프터, 선행 영 비트 카운팅 회로 등이 있다.
- 마이크로코드는 임시 레지스터 tmpA와 tmpB에 두 피연산자를 이동한 후 연산 유형에 따라 서브루틴으로 분기하며, 주소 #0232부터 시작하는 덧셈/뺄셈 마이크로코드는 1648개의 마이크로명령어를 통제하는 마이크로코드 롬에 저장된다.
- 덧셈 경로는 지수가 작은 수를 오른쪽으로 시프트해 정렬한 후 두 유효숫자를 더하고, 결과에 올림이 발생하면 오른쪽으로 1비트 시프트해 정규화하며, 뺄셈 경로는 결과가 음수일 수 있고 매우 작아질 수 있으므로 왼쪽으로 여러 비트 시프트해야 한다.
- 덧셈 연산이 실제로는 부호에 따라 내부적으로 뺄셈일 수 있고 반대도 마찬가지이며, 8087은 tmpA와 tmpB의 부호 비트를 XOR하여 어느 연산을 수행할지 판단하는 전용 회로를 가지고 있다.
- 결과가 0일 때는 정규화를 수행할 수 없으며, +0과 -0을 구분해야 한다: +0 + -0은 반올림 방식에 따라 -0(반올림) 또는 +0(다른 모드)이 된다.
- 선행 영 카운팅은 두 단계로 수행되는데, 먼저 선행 영 바이트 수만큼 왼쪽으로 시프트한 후 남은 선행 영 비트 수(0~7)를 카운팅하고 시프트하며, 총 시프트량을 임시 레지스터에 저장한다.
- 최종 지수는 원래 지수에서 tmpB의 지수 조정값(보통 0)을 빼고 expAdj 레지스터의 조정값을 더한 후 1을 빼서 계산하며, 지수 변환 회로는 오버플로우·언더플로우를 감지한다.
- 결과의 크기는 80비트, 64비트, 32비트 중 하나로 조정되며, ADJUST_PRECISION 서브루틴이 반올림으로 인한 지수 변경을 처리한다.
- 8087은 무한대, NaN, 비정규 수, 영(+0/-0) 등 특수 값을 수학적으로 합리적인 방식으로 처리하며, 공통 마이크로코드는 이러한 특수 경우들을 위해 18개의 조건부 분기로 구성된 '스파게티 코드'를 실행한다.
- 피연산자가 비정규 수이거나 특수 값(무한대, NaN, 영)인 경우를 감지하는 전용 회로가 있으며, 스택 언더플로우(빈 레지스터 접근)는 NaN을 반환하고 다양한 무한대·영 조합도 규정된 규칙에 따라 처리된다.