代码之家  ›  专栏  ›  技术社区  ›  fadedbee

为什么RV32I包含ADDI和XORI之类的指令,而不是BLTI?

  •  3
  • fadedbee  · 技术社区  · 6 年前

    https://riscv.org/specifications/ 第2章,第21页。

    (其中 B 大牧场 L 字母S T I 如果一个寄存器比一个常量小,那么mediate将把它与常量和分支进行比较。)

    我不知道的意见是,BLTI将经常用于C中的定长循环,例如:

    for (int i = 0; i < 16; i++) {
        ...
    }
    

    为什么算术和逻辑指令比分支指令更值得立即变量?

    1 回复  |  直到 6 年前
        1
  •  8
  •   user555045    6 年前

    分支已经需要将分支目标偏移量编码为立即数,在其中拟合两个立即数操作数会比较困难。使两者都小得多将使它们适合,但也会降低教学的有用性。

    这样的分支偶尔会有用,但在我看来,您高估了它的有用性:在典型的循环中,不需要直接将循环计数器与其边界值进行比较,事实上,大多数循环变量甚至都无法将其放入编译的代码中。

    作为一个小例子(使用更高的计数以避免循环完全展开),

    int test(int *data) {
        int sum = 0;
        for (int i = 0; i < 255; i++)
            sum += data[i];
        return sum;
    }
    

    由Clang编译成:

    test(int*):                              # @test(int*)
        addi    a2, zero, 1020
        mv      a3, zero
        mv      a1, zero
    .LBB0_1:                                # =>This Inner Loop Header: Depth=1
        add     a4, a0, a3
        lw      a4, 0(a4)
        add     a1, a4, a1
        addi    a3, a3, 4
        bne     a3, a2, .LBB0_1
        mv      a0, a1
        ret
    

    地址 然后循环,直到到达该地址,从循环中删除循环计数器。

    这是一个有点特殊的情况,但也有其他的伎俩。例如,在许多情况下,循环退出测试可以被转换为当寄存器被递减到零时退出的循环,这是因为RISCV已经很容易测试。 bnez . 原始循环计数器可以与必要时共存(不参与回路退出测试),或者如果可能的话,它可以再次消失。