




当遇到下个浮点算法指令时,往往会发生浮点异常(这就是预指令异常)。当存储一个浮点数到存储器或者到一个整数寄存器时会立即发生异常(这是已处理指令异常)。
注意因为结果是全面的,FMOVE 被认为是个算法指令。只有 FMOVE 的操作目的地不是浮点寄存器时(否则称为 FMOVE 溢出)能产生已处理指令异常。已处理指令异 常从不写目的地址。已处理指令异常发生后,继续处理下一条指令。
当浮点指令结果设置了 FPSR[EXC]位和相应的 FPCR[ENABLE]位被设置后,浮点运算异常变成了未定的。用户写 FPSR 和 FPCR 会导致 FPSR[EXC]的异常位连同相应 的 FPCR 的异常使能的重新设置,而 FPU 处于异常未定状态。在开始执行下一条算法 指令时会发生相应的预指令异常。
执行多个指令会产生多重异常。当多重异常发生并激活多个异常类时,优先级最高 的异常将被执行。这决定于异常管理者对多重异常的检查。下面是可能发生的多重异常:
一般来说,所有的异常都是相似的。如果异常条件存在,而异常不可捕捉,没有发 生异常,错误的结果将被写到目的地址(除 BSUN 异常没有目的地址),然后正常执行。
如果有效的异常发生,与以上讲到的相同的默认结果将被写到预指令异常中,但没 有结果写到已处理指令异常中。
我们期望异常处理将 FSAVE 作为第一条浮点指令。并且会清 FPCR,FPCR 用来阻 止异常处理期间发生异常。因为目的地址是写在浮点寄存器目的地址中的,原始的浮点 目的寄存器值对 FSAVE 状态的管理是可用的。指令地址引起的异常在 FPIAR 中是可用的。当异常处理完成时,需要清空 FSAVE 状态中适当的 FPSR 异常位,再执行FRESTORE。如果状态中的异常状态位没有被清空,相同的异常会再次发生。 相比较而言,执行FSAVE 异常处理可以简单的清除适当的 FPSR 异常位,任意改变 FPCR,并从异常中返回。注意异常从来不会随 FMOVE 发生在状态和控制寄存器中, 也不会随 FMOVEM 发生在浮点数据寄存器中。
在异常管理完成时,RTE 指令必须被执行返回到正常的指令流中。
11.1.5 分支开始无序(BSUN)
当无序条件存在时,IEEE 无意识的条件性测试与 FBcc 指令的联合会产生 BSUN。 在条件指令重启后任何一个浮点异常首先都是被预指令处理的。在执行条件指令之前条 件谓词会被估计和检查。当条件谓词是 IEEE 无意识的条件分支并且 FPCC[NAN]被置 位时就会发生 BSUN 异常发生。一旦条件被检测到,FPSR[BSUN]就被置位。表 11-4 显示了异常有效或是无效时的结果。

11.1.6 输入非数字(INAN)
INAN 异常是处理用户定义的机制,它不是 IEEE 的数据类型。输入的操作数不是 数字时,FPSR[INAN]被置位。有了 INAN 异常,用户可以忽略操作数为非数字的错误。 由于 FMOVEM、FMOVE、FPCR 和 FSAVE 指令不会改变状态位,所以不会产生异常。 所以这些指令在操作非数字类型时是有效的。见表 11-5。

11.1.7 输入规格化数字(IDE)
输入标准位 FPCR[IDE],为规格化操作数提供软件支持。当 IDE 异常无效时,操 作数被视为零,FPSR[INEX]被置位,操作成功。如果 IDE 异常有效且操作数是规格化 的,则发生 IDE 异常,但 FPSR[INEX]不置位以允许适当的置位处理。见表 11-6。
注意 FPU 从来不产生规格化数字。如果必要,软件会在下溢异常处理中创建。

11.1.8 操作数错误(OPERR)
操作数错误异常涵盖各种操作引发的问题,包括过少的或是过多的特殊异常条件的 错误。基本上,当对操作数的操作没有准确的解释时,操作数错误通常会发生。表 11-7 列出了操作数错误。异常发生时,FPSR[OPERR]置位。

表 11-8 描述了异常有效和无效时发生异常的结果。

11.1.9 溢出(OVFL)
当中间结果大于或等于已选择舍入精度的最大指数值时,目的地址是浮点寄存器或 存储器中的算法操作能检测到溢出异常。溢出只在目的地址为 S 或者 D 精度格式时发 生,对于其他格式管理类似操作数错误。在任何操作结束时,都可能发生溢出,检查中 间 结 果 以 防 下 溢 , 然 后 在 存 储 到 目 的 地 址 之 前 检 查 溢 出 。 如 果 溢 出 发 生 FPSR[OVFL,INEX]置位。
即使中间结果足够小可以被看成双精度数字,如果中间结果的数量级超出了所选舍 入精度格式的范围也会发生溢出。见表 11-9。

11.1.10 下溢(UNFL)
下溢异常发生是由于算法指令的中间结果太小而不能在浮点寄存器或存储器中用 已选择的舍入精度表示一个规格化数字。也就是说发生在中间结果指数小于或等于已选 舍入精度的最小指数值的情况下。下溢只在目的地址格式为单精度或双精度时发生。若 目的地址是一个字节,字或长字,则将下溢处理为0,从而不会引起下溢或操作数错误。 在任何操作结束时,都可能发生溢出,检查中间结果以防下溢,然后在存储到目的地址 之前检查溢出。如果溢出发生则 FPSR[UNFL]被置位。如果下溢无效,FPSR[INEX]被 置位。
即使中间结果足够大,可以被看成双精度数字,若它的数量级太小超出了所选舍入 精度格式的范围还是会发生下溢。见表 11-10 描述了异常有效或无效的结果。

11.1.11 除数为零(DZ)
若除法指令使用 0 作为除数会产生除数为零的异常。当检测到此异常时,FPSR[DZ]被置位。表 11-11 显示了异常有效或无效结果。

11.1.12 不精确结果(INEX)
当浮点类型中间结果的无穷精度尾数的关键位能在舍入精度或在目的格式中准确 的表示,INEX 异常就有可能发生。如果异常发生,FPSR[INEX]置位,无穷精度结果参 考表 11-12。

FPSR[INEX]在以下任何的条件下也会被置位:
表 11-13 显示了当异常有效或失效时的结果

11.1.13 MMU 转变成异常处理模式
当 MMU 模块出现在 ColdFire 芯片中,所有的存储器相关部件都需要对可恢复错 误(recoverable faults)提供支持。本节将详细描述 ColdFire 系列在加入 MMU 后的异常处 理模式的变化。
ColdFire 指令重启机制保证了错误的指令从执行开始重启,也就是说异常发生时没 有内部状态信息被保存,异常处理结束时没有被恢复。通过转变控制到给定的位置作为 RTE 指令的一部分,处理器使程序执行复原,给出异常堆栈结构中的 PC 地址定义。
如果指令发生后继错误,指令重启恢复模式需要程序可见寄存器改变执行到未完成模式。
对于 V4 及以上核心,大多数指令中操作数执行管道(OEP)结构自然支持这个概 念;只有在 OEP 末级也就是当错误的集合完成时,程序可见寄存器才会更新。任何类 型的异常发生,未定的寄存器更新都会被放弃。
大多数指令已经支持精度出错和指令重启。而一些复杂的指令不支持。思考以下存 储器到存储器的移动:
mov.l (Ay)+,(Ax)+ #从源地址复制四个字节数到目的地址 这条指令用了一周期去读源操作数(Ay)加 1 并将数据写到(Ax)。源和目的地址指针都被更新作为执行的一部分。表 11-14 列出了执行过程中的操作。

第二个周期中报告错误被检测到并且写到目的存储器中。此时,第一个周期的操作执行完成,所以如果目的写操作发生任何类型的访问错误,Ay 被更新。访问错误管理 执行完成后,错误指令重启,处理器操作是错误的因为源地址寄存器错误(已经存在的 增量)的值。
为了恢复所有指令的设计模式的初始状态,V4 及以上核心添加了必要的硬件来支 持全寄存器恢复。硬件允许程序可见寄存器存储多周期指令的原始状态,所以可支持指 令重启机制。存储器到存储器的移动和重载代表复杂指令需要的特殊恢复支持。