Почему RV32I содержит инструкции, такие как ADDI и XORI, но не BLTI?

Я не опытный в дизайне ISA. Я читал https://riscv.org/specifications/ главу 2, стр. 21.

Может ли кто-нибудь объяснить, почему в RISC-V есть арифметические и логические инструкции, которые используют непосредственные инструкции, такие как ADDI и XORI, но не похожи на инструкции условного перехода, такие как BLTI, BEQI и т. Д.

(Куда Bранчо LESS Tхань Immediate сравнил бы регистр с константой и ветвью, если бы он был меньше.)

Мое неосведомленное мнение состоит в том, что BLTI будет часто использоваться для циклов фиксированной длины в C, таких как:

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

Почему арифметические и логические инструкции более заслуживают непосредственных вариантов, чем отраслевые инструкции?

1 ответ

Решение

Ветвям уже нужно кодировать смещение цели ветвления как непосредственное, подгонка двух непосредственных операндов будет более сложной. Если сделать их обоих намного меньше, это позволит им соответствовать, но также уменьшит полезность инструкции.

Такая ветвь иногда может быть полезна, но, по моему мнению, вы переоцениваете ее полезность: в типичных циклах нет необходимости напрямую сравнивать счетчик цикла с его граничным значением, ведь большинство переменных цикла даже не превращают его в скомпилированный код.

В качестве небольшого примера (используя большее количество, чтобы избежать полного развертывания цикла),

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

Что Clang сделал здесь, так это вычисление окончательного адреса и затем зацикливание, пока этот адрес не будет достигнут, удаляя счетчик циклов из существования.

Это несколько особый случай, но есть и другие приемы. Например, во многих случаях тест выхода из цикла можно преобразовать в цикл, который завершается, когда регистр уменьшается до нуля, что легко проверить, так как RISCV имеет bnez, Исходный счетчик цикла может сосуществовать с ним при необходимости (без участия в тесте выхода из цикла), или он может снова исчезнуть, если это возможно.

Другие вопросы по тегам