beq
lyszt.net охоплює beq та інші інструкції RISC-V більш детально.
Формат кодування
Опис
beq дозволяє програмі прийняти рішення. Процесор зазвичай виконує інструкції в тому порядку, в якому вони з'являються у списку. Цей порядок сам по собі не може нічого вибрати або повторити. Розгалуження змінює порядок. Воно перевіряє умову, і якщо умова виконується, процесор продовжує в іншому місці замість наступного рядка. Усі оператори if та цикли побудовані з розгалужень.
Це інше місце названо міткою, ім'ям, за яким слідує двокрапка, що позначає позицію в коді, наприклад мітка done у прикладі. beq (branch if equal, розгалуження якщо рівно) порівнює два регістри. Коли вони містять однакове значення, воно переходить до позначеної позиції; коли вони відрізняються, виконання продовжується з наступною інструкцією. Форма показана нижче.
beq rs1, rs2, label
beq лише змінює, яка інструкція виконується наступною. Збереження результату так або ні порівняння як числа потребує іншої інструкції, описаної на сторінці slt.
Процесор відстежує свою позицію за допомогою регістра, який називається лічильником команд, що містить адресу інструкції, яка виконується. Виконане розгалуження змінює цю адресу, тому наступна інструкція береться з мітки.
Посібник RISC-V стверджує, що умовне розгалуження зберігає своє зміщення як 12-бітне значення, що відраховується в кратних 2 байтах. Зміщення розширюється зі знаком і додається до адреси інструкції розгалуження, даючи діапазон плюс або мінус 4 KiB, де KiB — це 1024 байти. Інструкції розгалуження порівнюють два регістри безпосередньо і не використовують кодів умов. Посібник наводить причину, що об'єднана інструкція порівняння та розгалуження вміщується у звичайний конвеєр і не потребує додаткового стану або тимчасового регістра. Він також радить програмному забезпеченню тримати найпоширеніший шлях як прямий код і очікувати, що зворотні розгалуження будуть передбачені як виконані, а прямі розгалуження як невиконані, принаймні першого разу, коли вони зустрічаються.
Розгалуження порівнює два регістри і не може прийняти константу, записану в інструкції, тому форма на кшталт beq t0, 5, label не існує. Щоб порівняти регістр з константою, спочатку завантажте константу в регістр за допомогою li, потім порівняйте два регістри.
li t1, 5 beq t0, t1, done
Значення 0 не потребує завантаження, тому що регістр zero завжди його містить.
Поширене використання порівнює регістр з zero, регістром, який завжди містить 0, щоб запитати, чи досягло значення нуля. Це завершує цикли зворотного відліку та перевіряє результати. Приклад розгалужується до done, коли a0 відрахувало до нуля. beq та мітки достатні, щоб побудувати кожне рішення та цикл у програмі.
Приклад
beq a0, zero, done # if a0 == 0, jump to 'done'
