PowerPC:如何使div/0返回零



我们正试图在PowerPC 8360上将传统应用程序从旧的单片RTOS移植到基于unix的RTOS。在旧系统中,我们的大型代码库依赖于1/0返回零和0/0返回零。现在,在新的操作系统中,1/0返回inf,0/0返回NaN,这破坏了我们的应用程序。我们试着玩FPSCR寄存器,但没有结果。

其次,如果有办法改变它,这种改变会影响我们的申请过程,而不是整个系统吗?我们不想更改系统中其他应用程序的div/0行为。

预见到不可避免的"你为什么要这样做"问题,我们必须保留以前的行为,因此将应用程序更改为实际上不除以零是不可能的。这是我们的一个痛点,所以请不要问。提前感谢!

注意:我已经有一段时间没有做过这种事情了。希望我的答案是大概的

当这种情况发生时,您需要捕获div-0异常——我相信MSR.FE0MSR.FE1以及FPSCR.VEFPSCR.ZE将需要进行操作,以确保以您想要的方式处理。

因此,一旦你设置好并开始工作,你就需要:

  • 控制这些场景(0/0和1/0)的异常处理。在我使用的大多数小型实时内核中,有了所有可用的源代码,我就知道该怎么做了。不知道你的RTOS是什么,也不知道你有多少控制权。很可能,如果它是一个"重量级"的操作系统,它不会让您篡改异常处理程序逻辑。我认为0/0将触发"无效操作"异常(FPSCR.VE),而1/0将触发IEEE浮点零除法异常(FPSCR.ZE)。

    • 如果得到Invalid Operation异常,则需要确定原因是0/0还是其他原因。有了0/0,就会设置FPSCR.VXZDZ(我想)。还有其他方法可以触发此异常,所以这里FPSCR是您的朋友。

    • 如果您得到IEEE FPdiv-0异常,则需要确定原因是1/0还是其他原因(例如2/0)。我认为为此,您必须检查中断上下文的寄存器,以查看在导致异常的除法运算时分子是否为1。FPU并不关心您是否尝试了1/02/0,但显然您的应用程序会这样做。

  • 接下来,您需要更改返回的上下文,以便获得所需的结果。这可能类似于更改操作中使用的FP寄存器,这样当您从exception&重新尝试FP除法,结果为零。例如,使分子0和除数1

然后,当您从异常返回时,应该会得到您想要的结果。对不起,我对特定的寄存器和值感到生疏,我希望这足以完成任务。

您还询问了是否仅为您的应用程序进程选择性地启用此行为。我以前不得不做这样的事情,但更多的是在平面地址空间中,"单进程、多线程"类型的内核(其中每个任务实际上是一个线程,所有任务都在同一平面地址空间内运行)。我已经用了几种不同的方法,这里有一些可能对你有用的想法:

  • 在异常处理程序中,检查进程ID/任务ID,如果它是您的应用程序进程,则以特殊方式处理,否则以标准的"系统"方式处理。

  • 或者,在应用程序的上下文切换上,安装针对此异常的"特殊"处理。在应用程序进程的上下文切换时,将其替换为标准处理。请注意,应用程序本身无法做到这一点,您必须进入内核才能做到(可能有一个上下文切换挂钩/调用可以使用,否则您可能会修改内核源代码)。

我以前继承过这样的遗留代码&我感觉到你的痛苦。你想对那些做出这种愚蠢行为的人挥舞拳头,但现在挥舞拳头对你运送产品没有帮助。你需要一个解决方案。祝你好运

如果您要迁移到符合POSIX的系统(如QNX或Linux),您可能需要尝试在应用程序中添加代码来捕获SIGFPE并处理那里的条件。

我不知道你在使用什么语言,而且(更重要的是)不担心在很长一段时间内捕捉信号,我不确定你会如何添加代码,但也许这个问题的答案(我如何在Linux C++中捕捉系统级异常?)会有所帮助。

最新更新