PowerPC:如何使div / 0结果返回零

问题描述

| 我们正在尝试将旧版应用程序从旧的整体式RTOS移植到PowerPC 8360上基于unix的RTOS上。在旧系统中,我们的大型代码库依赖于1/0返回零,而0/0返回零。现在在新的操作系统中,1/0返回inf,0/0返回NaN,这破坏了我们的应用程序。我们尝试使用FPSCR寄存器,但没有结果。 其次,如果有更改的方法,更改是否会影响我们的应用程序流程而不是整个系统?我们不想更改系统中其他应用程序的div / 0行为。 预料到不可避免的“您为什么要那样做”问题,我们必须保留以前的行为,因此将应用程序更改为实际上不被零除是不可能的。这是我们的痛处,请不要发问。提前致谢!     

解决方法

        注意:自从我从事此类工作已有一段时间了。希望我的答案在球场上。 您将需要捕获发生这种情况时发生的div-0异常-我相信将需要对
MSR.FE0
MSR.FE1
以及
FPSCR.VE
FPSCR.ZE
进行操作,以确保按照您想要的方式进行处理。 因此,一旦完成设置并开始工作,您将需要: 控制这些情况(0/0和1/0)的异常处理。在我使用的大多数小型实时内核中,在获得所有源代码的情况下,我都会知道该怎么做。不确定您的RTOS是什么或您拥有多少控制权。如果它是“重量级”的操作系统,则可能不会让您摆弄异常处理程序逻辑。 我认为
0/0
将触发\“ Invalid Operation \”异常(
FPSCR.VE
),而
1/0
将触发IEEE浮点零除异常(
FPSCR.ZE
)。 如果收到“无效操作”异常,则需要确定原因是“ 4”还是其他原因。用
0/0
,将设置
FPSCR.VXZDZ
(我认为)。还有其他触发此异常的方法,因此
FPSCR
是您的朋友。 如果您收到IEEE FP div-0异常,则需要确定原因是“ 6”还是其他原因(例如“ 13”)。我认为,为此,您必须检查中断上下文的寄存器,以查看导致异常的除法运算时分子是否为14。 FPU不管您尝试的是
1/0
还是
2/0
,但显然您的应用程序会这样做。 接下来,您需要更改返回的上下文,以便获得所需的结果。这可能类似于更改操作中使用的FP寄存器,以便当您从异常返回且FP除法重试时,它产生零。例如,使分子
0
和除数
1
。 然后,当您从异常中返回时,您应该获得所需的结果。抱歉,我对特定的寄存器和值不满意,我希望这足以完成工作。 您还询问了仅针对应用程序过程有选择地启用此行为的问题。我以前必须做过这样的事情,但是在平面地址空间中,更多的是“单个进程,多个线程”类型的内核(每个任务实际上是一个线程,都在相同的平面地址空间中运行)。我已经通过几种不同的方式完成了此操作,以下一些想法可能对您有用: 在异常处理程序中,检查进程ID /任务ID,如果它是您的应用程序进程,则以特殊方式进行处理,否则以标准的“系统”方式进行处理。 或者,在上下文切换到您的应用程序中时,为此异常安装“特殊”处理。在上下文退出应用程序流程时,将其替换为标准处理。请注意,应用程序本身将无法执行此操作,您必须进入内核才能执行此操作(可能会使用上下文切换钩子/调用,否则您可能会修改内核源代码)。 我以前曾继承过这样的旧代码,我感到您很痛苦。您想对安装这种骨头的行为的人握拳,但是现在握拳并不能帮助您运送产品。您需要一个解决方案。祝好运。     ,如果要迁移到POSIX兼容系统(例如QNX或Linux),则可能要尝试在应用程序中添加代码以捕获SIGFPE并在那里处理条件。 不知道您使用的是哪种语言,并且(更重要的是)不很长时间就不担心捕获信号,我不确定您将如何添加代码,但是不确定这个问题的答案(如何捕获) Linux C ++中的系统级异常?)会有所帮助。