MIPS异常处理(特别是分支延迟槽)

时间:2011-01-03 18:41:49

标签: exception-handling mips

假设在条件分支的分支延迟槽中遇到异常

e.g。

    BEQ a0, zero, _true
    BREAK (0000)
    sw a0, 0000(t0)
_true:
    sw a1, 0000(t0)

我的异常处理程序将从 BREAK 指令中选择类型9 异常,并设置 CAUSE <的 BD 位/ em>在分支延迟中注册为1,EPC将是分支的地址。

文档说这将需要复杂的处理,这是没有描述的。即获取分支/跳转的目标,进行任何所需的比较,然后将PC设置为真或假地址。

我解决复杂处理(这有点像黑客攻击)的解决方案如下:

  1. 将指令存储在分支延迟槽
  2. NOP分支延迟槽中的指令
  3. 从异常处理程序返回,恢复所有寄存器
  4. 重新执行* BEQ a0,zero,_true *并且分支延迟将是一个nop因此它将没有任何效果
  5. 在分支的目标处放置一个sw断点并设置一个标志
  6. 一旦命中了sw断点,就恢复分支延迟槽并删除sw断点的痕迹。
  7. 解析分支和跳转很好(因此我可以获得目标)但是在条件分支中,一旦我解析了,我就必须进行比较以确定是否跳转到真正的部分转到false (下一行)我认为比我想要的工作更多。 我不是吗?

    我的hacky方法的问题是:

    CPU是否已经存储它已经命中条件分支并且已经确定在执行分支延迟槽之后是否将采用分支,因此一旦我指向程序计数器< / em>回到分支并且它被执行而不是正确执行它认为它必须跳转到在异常发生之前预先确定的分支的真或假部分? (尝试“双跳”)

1 个答案:

答案 0 :(得分:1)

你有MIPS程序员的文件吗?如果你想要一个100%准确的答案读它们 - 如果不是我可以告诉你重要的一点,因为我记得它们。

简而言之 - 是的,您需要从内存加载指令,解析它并解释结果以确定您必须继续的位置。 “修补”你所表达的代码也会起作用,但你需要确保指令缓存失效,否则你将从缓存中运行并以无限循环结束。

在执行延迟槽之后,PC的更新将跟随,直到它将指向分支。在例外期间没有特殊处理,除非您有一个寄存器,表明您是否在延迟槽中。 你需要模拟所有可以在处理程序(加载/存储)中有条件地引发异常的指令以及分支指令。如果DS中的另一种指令你可以在分支处重启(在这种情况下是一个外部中断)。

如果您关心的是性能,那么就不要将异常提示指令放在延迟槽中。

编辑:不,MIPS没有存储任何关于被中断指令的内容,但是由于必须使ICache无效两次,你建议的方法可能会更慢