Inside the Intel 8087 chip: floating-point addition and subtraction
本文为原文前 6,000 字符的节选翻译,完整内容请查看原文。
Inside the Intel 8087 chip: floating-point addition and subtraction. In 1980, Intel introduced the 8087, a chip that made floating-point operations much faster in the IBM PC and other systems. Although the 8087 supports advanced operations such as tangents, square roots, and logarithms, this article focuses on basic arithmetic operations: addition and subtraction. The 8087 provided a spectacular speed improvement over the 8086 processor, speeding up addition by a factor of almost 100, and complicated operations by even more.
Intel 8087 芯片内部:浮点加法与减法。1980 年,Intel 推出了 8087 芯片,该芯片使 IBM PC 及其他系统中的浮点运算速度大幅提升。尽管 8087 支持正切、平方根和对数等高级运算,但本文重点介绍基本的算术运算:加法和减法。与 8086 处理器相比,8087 提供了惊人的速度提升,将加法速度提高了近 100 倍,复杂运算的提升幅度甚至更大。
In this article, I examine the 8087’s microcode and circuitry to explain exactly how floating-point addition and subtraction are implemented, including numerous special cases for infinities and other special values. To explore the 8087’s circuitry, I popped the lid off a chip with a chisel and used a microscope to create the high-resolution image below. The microcode ROM is the large rectangular region in the center of the die, holding the 1648 micro-instructions that control the chip. The bottom half of the chip (red box) is the datapath, the circuitry that performs floating-point calculations on 80-bit values.
在本文中,我将研究 8087 的微代码和电路,以解释浮点加法和减法究竟是如何实现的,包括针对无穷大和其他特殊值的众多特殊情况。为了探索 8087 的电路,我用凿子撬开了芯片盖,并使用显微镜制作了下方的高分辨率图像。微代码 ROM 是芯片中心的大型矩形区域,包含控制芯片的 1648 条微指令。芯片的下半部分(红色框)是数据通路,即对 80 位数值执行浮点计算的电路。
A close-up of the 8087’s datapath, showing functional blocks that are used for addition and subtraction. Click this image (or any other) for a larger version. Zooming in on the datapath shows the functional blocks that are important for addition and subtraction. The key component is the integer adder, located in the center. It receives one argument from the B register and another argument from a component such as the temporary registers or the stack registers. The adder’s output is stored in the sum register.
8087 数据通路的特写,展示了用于加法和减法的功能模块。点击此图像(或任何其他图像)可查看大图。放大数据通路可以看到对加法和减法至关重要的功能模块。关键组件是位于中心的整数加法器。它从 B 寄存器接收一个参数,并从临时寄存器或堆栈寄存器等组件接收另一个参数。加法器的输出存储在和寄存器中。
The shifter can shift the bits in a value to the left or the right. The shifter occupies a lot of space on the die because its circuitry allows a value to be rapidly shifted by an arbitrary number of bits. Floating-point operations make heavy use of the shifter to align values; the leading zero circuitry counts the number of zero bits or bytes on the left of a value so they can be shifted away. The exponent converter processes exponents, detecting overflows and underflows. These specialized circuits helped the 8087 achieve its high performance.
移位器可以将数值中的位向左或向右移动。移位器在芯片上占据了很大空间,因为其电路允许数值快速移动任意位。浮点运算大量使用移位器来对齐数值;前导零电路计算数值左侧零位或字节的数量,以便将它们移出。指数转换器处理指数,检测溢出和下溢。这些专用电路帮助 8087 实现了高性能。
Floating-point addition and subtraction. Most computers use integers as their basic representation for numbers. But many applications need to use numbers with a fractional part, such as 1.23. Moreover, integers have a very limited range: a 32-bit integer can express numbers from about -2 billion to 2 billion. To solve these problems, computers usually implement floating-point numbers, which provide fractional numbers over an enormous range.
浮点加法和减法。大多数计算机使用整数作为数字的基本表示形式。但许多应用需要使用带有小数部分的数字,例如 1.23。此外,整数的范围非常有限:32 位整数只能表示约 -20 亿到 20 亿之间的数字。为了解决这些问题,计算机通常实现浮点数,它可以在巨大的范围内提供小数。
In most cases, a floating-point number is represented by sign × significand × 2exponent. The significand is a binary number of the form 1.bbb…: a leading 1, followed by the binary point (the binary equivalent of the decimal point) and the rest of the bits. In a binary number, each bit represents a power of 2. For the fractional part, the part after the binary point, the powers of 2 are negative: 2-1, 2-2, and so forth. So the binary number 1.1 is 1 + 1/2, or 1.5 in decimal. Similarly, binary 1.0011 is 1 + 1/8 + 1/16 or 1.1875.
在大多数情况下,浮点数由“符号 × 尾数 × 2的指数”表示。尾数是一个形式为 1.bbb… 的二进制数:一个前导 1,后跟二进制小数点(十进制小数点的二进制等价物)以及其余位。在二进制数中,每一位代表 2 的幂。对于小数部分(即二进制小数点之后的部分),2 的幂是负数:2^-1、2^-2 等等。因此,二进制数 1.1 等于 1 + 1/2,即十进制的 1.5。同样,二进制数 1.0011 等于 1 + 1/8 + 1/16,即 1.1875。
The exponent allows numbers to escape the limited range of the significand. For instance, 1.1 (binary) × 28 is 384. With larger exponents, floating-point numbers can cover a huge range; even a 32-bit short floating-point number covers a range exceeding 10-36 to 1038. Floating-point addition and subtraction are more complicated than integer operations. Before the numbers can be added (or subtracted), their binary points must be aligned, the same as aligning the decimal points for decimal numbers. After the operation, the exponent of the result must be adjusted, normalizing the significand so it starts with a 1 bit.
指数使数字能够突破尾数的有限范围。例如,1.1(二进制)× 2^8 等于 384。通过更大的指数,浮点数可以覆盖巨大的范围;即使是 32 位短浮点数,其范围也超过 10^-36 到 10^38。浮点加法和减法比整数运算更复杂。在数字相加(或相减)之前,必须对齐它们的二进制小数点,这与对齐十进制数字的小数点相同。运算后,必须调整结果的指数,对尾数进行归一化,使其以 1 位开头。
The steps for a simple floating-point addition. The diagram above illustrates a simple floating-point addition: 13.5+3.5. The first two lines show the two arguments expressed with an exponent and significand. Both arguments are normalized, so the leftmost bit is a 1. Before adding, the second argument must be aligned—making the exponents equal—by shifting it two positions to the right. (The difference between the exponents in this case is two.) The values are then added, using integer addition on the aligned significands. In this case, adding the values causes an overflow, an “extra” bit on the left. The result must be normalized by shifting it one position to the right and incrementing the exponent by 1.
简单浮点加法的步骤。上图说明了一个简单的浮点加法:13.5 + 3.5。前两行显示了用指数和尾数表示的两个参数。两个参数都已归一化,因此最左边的位是 1。在相加之前,必须通过将第二个参数向右移动两个位置来对其进行对齐(使指数相等)。(在这种情况下,指数之间的差为 2。)然后,使用对齐后的尾数进行整数加法来相加这些值。在这种情况下,相加会导致溢出,即左侧出现一个“额外”位。必须通过将结果向右移动一个位置并将指数增加 1 来对结果进行归一化。
Floating-point subtraction is similar, but has a few more complications. The result can be positive, negative, or zero. The result can be orders of magnitude smaller than the arguments. The figure below shows a basic subtraction, 8-7.5. As with addition, the second argument is shifted right so the exponents match (i.e., the binary points line up). The two significands are subtracted with integer subtraction. The result is normalized by shifting to the left so the top bit is a 1. Unlike the addition case, normalization may require a large shift. In this case, the shift is four bits and the exponent is decremented by 4 to yield the result.
浮点减法类似,但有更多复杂之处。结果可能是正数、负数或零。结果可能比参数小几个数量级。下图显示了一个基本减法:8 - 7.5。与加法一样,第二个参数向右移动以匹配指数(即二进制小数点对齐)。两个尾数通过整数减法进行相减。通过向左移动使最高位为 1 来对结果进行归一化。与加法情况不同,归一化可能需要大幅度移位。在这种情况下,移位为 4 位,指数减去 4 以得出结果。
A simple floating-point subtraction. One complication with subtraction is that the result can be negative. If that occurs, the significand is made positive, and the sign of the result is flipped. Subtraction can also result in zero. In this case, normalization cannot be performed; instead, a special value +0 or -0 is returned as appropriate.
简单的浮点减法。减法的一个复杂之处在于结果可能是负数。如果发生这种情况,尾数将变为正数,并且结果的符号将被翻转。减法也可能导致零。在这种情况下,无法执行归一化;相反,会根据情况返回特殊值 +0 或 -0。
Relevant hardware details of the 8087. In this section, I’ll explain some features of the 8087 that play important roles in the microcode implementation of addition and subtraction. The 8087 supports a variety of data types, but internally, the 8087 stores numbers in an 80-bit format called “temporary real”. A temporary real number has a sign bit, a 15-bit exponent, and a 64-bit significand. The 15-bit exponent allows numbers that are absurdly large, over 104932.
8087 的相关硬件细节。在本节中,我将解释 8087 的一些特性,这些特性在加法和减法的微代码实现中起着重要作用。8087 支持多种数据类型,但在内部,8087 以一种称为“临时实数”的 80 位格式存储数字。临时实数具有一个符号位、一个 15 位指数和一个 64 位尾数。15 位指数允许表示极其巨大的数字,超过 10^4932。