报名编号:CICC1327
团队名称:301小队
fcsr寄存器包含浮点异常标志位域 Cfflags ),不同的异常标志位所表示的异常如下图所示。如果浮点运算单元在运算中出现了相应的异常,则会将fcsr寄存器中对应的异常标志位设置为高,且会一直保持累积。软件可以通过写0的方式单独清除某个异常标志位。
在很多的处理器架构中,浮点运算产生结果异常都会触发异常跳转,进入异常模式。RISC-V 架构的浮点指令在产生结果异常时并不会跳转进入异常模式,而是如上所述仅设置fcsr寄存器中的异常标志位。这是 RISC-V 架构一个显著特点。该特点可以大幅简化处理器流水线的硬件实现。
五种异常类型:
无效操作
被0除
上溢
下溢
不精确异常
以上五种异常类型只会出现在浮点运算指令中,浮点读写指令、浮点整数相互搬指令、浮点分类指令、浮点数符号注入指令不会产生异常。
此外,有的指令只会产生一种异常
对于产生浮点格式结果的操作,发出无效操作异常信号的操作的默认结果应为qNAN
如果一个操作数为Signaling-NaN,则产生无效操作,除了一些特殊情况
以下是产生无效操作的情况:
(1)对于乘法指令,如果两个操作数为(0, ∞) 或者(∞, 0)。
(2)对于乘加指令三个操作数为(0, ∞, c) 或者(∞, 0, c),如果c为qNaN,则由实现着决定是否产生无效操作异常。
(3)对于加减,乘加指令,产生无穷大幅度的加减运算,如加法运算(+∞, −∞)。
(4)除法:除法(0,0)或除法(∞,∞)。
(5)开放运算:开放值小于0。
(6)当结果不符合目标格式时,或者当一个操作数是有限的而另一个是无限的时。
特殊情况:
(1)对于 FMAX FMIN 指令:如果指令的两个操作数都是 NaN ,那么结果为 Canonical-NaN;如果只有一个操作数为 NaN 结果为非 NaN 另外一个操作数;如果任意一个操作数属于 Signaling-NaN ,则需要产生无效常。
(2)对于FSGNJ, FSGNJN FSGNJX指令,NaN类型的操作数并不做特殊对待,而是将其当作普通操作数一样进行符号注入操作。
(3)对于FLT、FLE和FEQ指令,果任何一个操作数为NaN,则结果为0;对于FLT、FLE指令,如果任意一个操作数属于NaN需要产生无效操作异常;对于 FEQ 指令,如果任意一个操作数属于 Signa NaN,则产生无效操作异常。
很显然只会发生在除法指令中,当除数为零并且被除数是有限的非零值时,其默认结果应为一个带符号的无穷,无穷大的符号是操作数符号的异或。
当计算导致数字过大,超过了当前类型所能表达的范围时,就会发生上溢
下溢比较复杂,一个例子:存在这样一个数,它的指数部分是最小值,即由全部可用位表示的最小尾数值。该数字是float类型能用全部精度表示的最小数字。现在把它除以2。通常,这个操作会减小指数部分,但是假设的情况中,指数是最小值了,所以计算机只好把尾数部分的位向右移,空出1个二进制位,并丢弃最后一个二进制数。以十进制为例,把一个4位有效数字的数(如,0.1234E-10)除以10,得到的结果是0.123E-10.虽然得到了结果,但是在计算过程中却损失了原本尾有效位上的数字。这种情况叫做下溢。
对于一些特殊的运算会产生不精确的值,比如除法运算和开放运算会产生无限的小数位,浮点转整数指令会舍去小数值,其结果不精确。