Использование SLLI для доступа к элементам массива в цикле - PullRequest
3 голосов
/ 16 января 2020

Это пример, который мой учитель привел в C:

while (save[i] == k) i+=1;            

Скомпилировано в режиме RIS C -V, где i в x22, k в x24, save адрес в x25:

slli x10,x22,3                
add  x10,x10,x25   
ld   x9, 0(x10)   
bne  x9,x24, EXIT  
addi x22,x22,1  
beq  x0,x0, Loop  
Exit:.....

Я не понимаю, почему он использовал сдвиг влево при немедленном (slli)

1 Ответ

3 голосов
/ 16 января 2020

Я не понимаю, почему он использовал сдвиг влево при немедленном (slli)

Смещение влево числа N битов дает тот же результат, что и умножение числа на 2 N . Поскольку инструкция умножения обычно более дорогая (медленнее), чем инструкция сдвига, сдвиг влево используется вместо инструкции умножения в качестве оптимизации, когда это возможно: если один из операндов имеет постоянную степень двух.


slli используется для вычисления смещения в массив save. Поскольку i соответствует x22, то:

slli x10,x22,3

умножает значение i на 8 (т. Е. 2 3 (степень двойки) и записывает этот результат в x10.

x25 указывает базовый адрес массива save - адрес его первого элемента - save[0]. Вместе с x10, который соответствует смещению , используется для вычисления адреса save[i]:

add  x10,x10,x25

В этот момент x10 содержит адрес save[i]. Этот элемент в конечном итоге загружается в x9:

ld   x9, 0(x10)
...