Почему RV32I содержит инструкции, такие как ADDI и XORI, но не BLTI?
Я не опытный в дизайне ISA. Я читал https://riscv.org/specifications/ главу 2, стр. 21.
Может ли кто-нибудь объяснить, почему в RISC-V есть арифметические и логические инструкции, которые используют непосредственные инструкции, такие как ADDI и XORI, но не похожи на инструкции условного перехода, такие как BLTI, BEQI и т. Д.
(Куда B
ранчо L
ESS T
хань I
mmediate сравнил бы регистр с константой и ветвью, если бы он был меньше.)
Мое неосведомленное мнение состоит в том, что 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
, Исходный счетчик цикла может сосуществовать с ним при необходимости (без участия в тесте выхода из цикла), или он может снова исчезнуть, если это возможно.