【问题标题】:Why does JALR encode the LSB of the offset?为什么 JALR 对偏移量的 LSB 进行编码?
【发布时间】:2020-04-16 05:58:37
【问题描述】:

我们知道jal 指定了一个 21 位的偏移量。但是,它不编码 21 位偏移量,而是 20 位偏移量。原因是地址的最低有效位总是为零,因为最小可能的 RISC-V 指令是 2 个字节,所以该位没有在指令中编码。

通过这种方式对偏移进行编码,它可以提供 ±1MiB 的跳跃范围。如果jal 确实对 LSB 进行了编码,那么它只会提供 ±512KiB 的跳跃范围。

但是,指定 12 位偏移量的 jalr 指令确实对 LSB 进行了编码。这会将跳跃范围减小到 ±2kiB(而不是 ±4kiB)。我知道jalr 使用I 型格式,与addi 相同,并且对于这种指令必须对立即数的LSB 进行编码。但是,我看不出为什么必须为jalr 编码最低有效位。

【问题讨论】:

  • 与许多其他类似问题不同,我认为该指令集的创建者还活着,您可以尝试联系他们。明白这样的决定并不总是技术性的,而只是他们碰巧选择的。也许范围无关紧要,逻辑的实现可能比跳跃范围更重要。在任何一种情况下,选择这条路都是某人或某个会议或某些团体的意见,而不必有技术/固定/理智的原因。
  • 作者的姓名应该在 risc-v 规范中,您可以直接联系其中一位或多位作者来解决这个基于意见的问题。

标签: assembly riscv instruction-set instruction-encoding


【解决方案1】:

JALR 用于两个相对不同的目的:

  • 间接分支,例如
    • 函数返回
    • 间接函数调用(例如函数指针;vtables/虚拟调度),以及,
  • 中远分支(在两个指令序列中,具有 32 位 pc 相对范围)。

对于前者的间接分支,立即数始终为 0,也就是说实际上根本没有使用立即数!

对于后者,该指令与AUIPC 结合使用,形成PC 相对寻址的高20 位——然后JALR 结合使用形成低12 位,总共32 位的 pc 相对偏移量。

但是,AUIPC 既用于远程分支,也用于 pc 相关数据访问。因此,它们都共享 12 位偏移量——加载/存储使用它们的 12 位立即数,而JALR 也使用 12 位立即数字段,就像加载和存储一样。设计者选择共享AUIPC,而不是为这两种用途使用两个不同的AUIPC(从代码到代码的引用与从代码到数据的引用)。

综上所述,JALR 的范围大多并不重要,只要它可以提供剩余的 12 位来补充AUIPC 的 20 位即可。当然还有其他方法,但这确实具有重复使用的优势,并且只需要一条AUIPC 指令。

【讨论】:

    【解决方案2】:

    原因已在RISC-V spec 中说明:

    请注意,与条件分支指令不同,JALR 指令不会将 12 位立即数视为 2 个字节的倍数。这避免了硬件中的一种更直接的格式。在实践中,JALR 的大多数使用要么立即数为零,要么与 LUI 或 AUIPC 配对,因此范围的轻微减少并不显着。

    在计算 JALR 目标地址时清除最低有效位既可以稍微简化硬件,也可以使用函数指针的低位来存储辅助信息。尽管在这种情况下可能会丢失一些错误检查,但实际上跳转到错误的指令地址通常会很快引发异常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      • 2020-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多