【问题标题】:PowerPC: How to make div/0 return zero as a resultPowerPC:如何使 div/0 作为结果返回零
【发布时间】:2011-06-23 21:01:37
【问题描述】:

我们正在尝试将遗留应用程序从旧的单片 RTOS 移植到 PowerPC 8360 上基于 unix 的 RTOS。在旧系统中,我们的大型代码库变得依赖于 1/0 返回零和 0/0 返回零.现在在新的操作系统中,1/0 返回 inf,0/0 返回 NaN,这会破坏我们的应用程序。我们尝试过使用 FPSCR 寄存器,但没有任何结果。

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

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

【问题讨论】:

  • 有什么阻止您为受影响的模块定义本地宏?

标签: rtos powerpc qnx qnx-neutrino


【解决方案1】:

注意:我已经有一段时间没有从事这种工作了。希望我的答案是大致的。

您需要捕获发生这种情况时发生的 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 FP div-0 异常,您需要确定原因是 1/0 还是其他原因(例如 2/0)。我认为为此,您必须检查中断上下文的寄存器,以查看在导致异常的除法运算时分子是否为1。 FPU 不关心您是否尝试了1/02/0,但显然您的应用程序会这样做。

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

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

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

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

  • 或者,在上下文切换到您的应用程序时,为此异常安装“特殊”处理。在应用程序进程的上下文切换时,将其替换为标准处理。请注意,应用程序本身无法执行此操作,您必须利用内核来执行此操作(可能有一个您可以使用的上下文切换挂钩/标注,否则您可能会修改内核源代码)。

我以前继承过这样的遗留代码,我感受到了你的痛苦。您想对安装这种愚蠢行为的人挥舞拳头,但现在挥舞拳头并不能帮助您发布产品。你需要一个解决方案。祝你好运。

【讨论】:

  • 非常感谢。我认为我们将与 RTOS 人员一起确定要使用哪些浮点寄存器,但这似乎是我们正在寻找的解决方案。
  • 请注意,glibc 支持在用户空间中使用feenableexcept(FE_DIVBYZERO|FE_INVALID) 启用异常(您应该获得 SIGFPE);这需要操作系统支持,因此可能不相关(而且我认为 C99 没有提供明显的方法来启用某些浮点陷阱)。
【解决方案2】:

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

不知道您使用的是什么语言,并且(更重要的是)不用担心长时间捕获信号,我不确定您将如何添加代码,但也许是这个问题的答案(@987654322 @) 会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    相关资源
    最近更新 更多