【问题标题】:How does RISC-V variable length of instruction work in detail?RISC-V变长指令具体是如何工作的?
【发布时间】:2019-11-14 09:05:23
【问题描述】:

浏览 risc-v isa doc 后,给我的印象是 riscv 支持 16bits(RVC)、32bits(RV32I)、64bits(RV64I) 长度的指令。

对于 RV32I:立即数有符号扩展到 32 位

  • 指令长度:32 位
  • 寄存器大小:32 位
  • 内存地址:32位

对于 RV64i:立即数有符号扩展到 64 位

  • 指令长度:32 位
  • 寄存器大小:64 位
  • 内存地址:64位

似乎 RV32I 和 RV64I 都使用 32 位指令大小,差异与符号扩展的大小有关。

我认为大指令大小允许您在指令中编码大立即数,这应该比小指令大小更好,因为它很容易耗尽空间。

对于risc-v,RV64I,如果只使用32位指令长度,64位寄存器文件和内存地址,如何充分利用硬件资源。 (例如,直接跳转到一个大内存地址。)

一般情况下,RV64I的命名是否应该表明指令长度为64位?

【问题讨论】:

    标签: riscv instruction-set


    【解决方案1】:

    RISC-V 允许混合 16 位、32 位、48 位、64 位等指令!

    RV32I 定义了 32 位计算机体系结构,其中寄存器为 32 位宽。它的指令都是 32 位宽的。例如,lw 将 32 位字加载到寄存器中,add 添加两个寄存器并定位第三个。

    RV64I 定义了 64 位计算机体系结构,其中寄存器为 64 位宽(因此 RV64)——其指令也是 32 位宽。 RV32 指令仍然有效,并且还有一些额外的指令可以同时适应 32 位和 64 位操作。例如,lw 仍然加载一个 32 位字(尽管现在符号扩展以填充 64 位寄存器),因此使用新指令 ld 加载一个 64 位字。 add 仍然添加两个寄存器并以第三个为目标,但同样的 add 现在正在执行 64 位加法而不是 32 位加法,因为寄存器在 RV64 中是 64 位的。一条新指令 addw 执行 32 位加法,以防万一这就是您想要的。

    RVC 是可以添加到 RV32I 或 RV64I 的扩展。当它出现时,它允许 16 位指令,并且它的设计是这样的,即 16 位指令将 1:1 扩展为 32 位宽指令——因此,寄存器架构(无论是 RV32或添加了 RVC 的 RV64),从某种意义上说,在 32 位宽的指令集中,他们没有什么新东西可以做。我们应该更多地认为它是一种节省空间的技术,而不是一些新功能。

    基本架构(即没有 RVC)允许分支到 16 位边界。 PC 和返回地址以及所有分支指令都支持任何偶数字节值,因此当将 RVC 添加到某物时,其他指令不会改变。此工件还支持 48 位和 64 位指令,但尚未为这些大小定义扩展。

    但是,指令集保留了足够的操作码空间,可以区分 16 位、32 位、48 位和 64 位指令。以二进制 11 开头的指令(在指令的最低位位置)是 32 位大小的指令(但保留了一种模式:因此它们不能以 11111 开头)。紧凑指令在同一位置使用 00、01 和 10。 48位指令以011111开头,64位指令以0111111开头。

    基本架构还对所有内容使用 pc 相对分支,因此您可以构建一个代码段大至 4GB 的可执行映像(加载时,它可以位于 64 位地址空间中的任何位置)。

    RV32I 和 RV64I 似乎都使用 32 位指令大小,差异与符号扩展的大小有关。

    RV32 与 RV64,寄存器从 32 位扩展到 64 位,所以,是的,当 RV64 发生符号扩展时,它会扩展到 64 位。

    我认为大指令大小允许您在指令中编码大立即数,这应该比小指令大小更好,因为它很容易耗尽空间。

    RISC V 指令集是在对 MIPS(早期的 RISC 设计)进行多年研究后设计的。与具有可变长度指令大小的 x86 相比,MIPS 并没有为 40 多年的演进留下足够的操作码空间。固定大小的指令集是代码空间和功能之间的折衷——指令大小越大,可以编码的越多,但会牺牲代码密度。代码密度对性能的影响很大,因此不容忽视。因此,RISC V 允许使用可变大小的指令,如果您愿意,可以在您的实现中创建 256 位指令!

    对于risc-v,RV64I,如果只使用32位指令长度,64位寄存器文件和内存地址,如何充分利用硬件资源。 (例如,直接跳转到一个大内存地址。)

    可执行程序映像的代码最大可达 4GB,并且仍然使用 pc 相对分支——它将使用我们所说的远分支,其中分支序列由两条指令(auipcjal)。需要明确的是,4GB 是一个非常大的代码段。 64 位架构的大部分价值在于能够处理超过 4GB 的数据,而不是超过 4GB 的代码。要达到超过 4GB 的代码大小,您将使用指针(例如存储在表中),因为指针可以是完整的 64 位宽。这种技术已经用于 DLL(即使当它们的大小加在一起时它们通常不会超过 4GB 的代码),因为它们通常是独立加载的(因此,相对于 pc 的分支将在单个代码段,在代码段之间是行不通的)。

    一般情况下,RV64I的命名是否应该表明指令长度为64位?

    因为,无论我们拥有何种架构(例如 16 位、32 位、64 位),在我们用完代码空间之前,我们往往会用完数据空间,这是 64 位的主要特征体系结构是它对 64 位地址空间的支持,允许大量内存用于数据。这种对大型地址总线的支持还附带使用 64 位地址的能力,当然也可以操作 64 位值。因此,RV64 的重要之处在于 64 位寄存器以及使用 64 位值来寻址内存的能力。 (指令大小是一个正交问题。)

    【讨论】:

    • 如果我想设计 256 位指令,我仍然应该支持所有基本的 RV32I 指令集。因此,在二进制文件中,code(.text) 部分将包含 32 位和 256 位指令的混合。我对这个概念是否正确?
    • 是的,如果您想使用 RISC V,您可以设计扩展,因此您仍然希望支持基本的 RV32I 或 RV64I。您的 256 位指令将与 32 位基本集(如果您还支持 RVC,则为 16 位)很好地混合。
    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 2018-11-22
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    • 2018-05-16
    相关资源
    最近更新 更多