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'
