beq

beq

Asembler RISC-V Referencja

lyszt.net obejmuje beq i inne instrukcje RISC-V w większych szczegółach.

Format kodowania

R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

Opis

beq pozwala programowi podjąć decyzję. Procesor normalnie wykonuje instrukcje w kolejności, w jakiej pojawiają się na liście. Ta kolejność sama w sobie nie może niczego wybrać ani powtórzyć. Rozgałęzienie zmienia kolejność. Testuje warunek, a jeśli warunek jest spełniony, procesor kontynuuje w innym miejscu zamiast w następnej linii. Wszystkie instrukcje if i pętle są zbudowane z rozgałęzień.

To inne miejsce jest nazwane przez etykietę, nazwę po której następuje dwukropek, oznaczającą pozycję w kodzie, taką jak etykieta done w przykładzie. beq (branch if equal, rozgałęzienie jeśli równe) porównuje dwa rejestry. Gdy przechowują tę samą wartość, skacze do oznaczonej pozycji; gdy się różnią, wykonanie kontynuuje z następną instrukcją. Forma pojawia się poniżej.

beq rs1, rs2, label

beq zmienia tylko, która instrukcja zostanie wykonana jako następna. Przechowywanie wyniku tak lub nie porównania jako liczby wymaga innej instrukcji, opisanej na stronie slt.

Procesor śledzi swoją pozycję za pomocą rejestru zwanego licznikiem programu, który przechowuje adres instrukcji, która jest wykonywana. Wykonane rozgałęzienie zmienia ten adres, więc następna instrukcja pochodzi z etykiety.

Podręcznik RISC-V stwierdza, że warunkowe rozgałęzienie przechowuje swój offset jako wartość 12-bitową liczoną w wielokrotnościach 2 bajtów. Offset jest rozszerzany znakowo i dodawany do adresu instrukcji rozgałęzienia, dając zakres plus lub minus 4 KiB, gdzie KiB to 1024 bajty. Instrukcje rozgałęzienia porównują dwa rejestry bezpośrednio i nie używają kodów warunków. Podręcznik podaje powód, że połączona instrukcja porównania i rozgałęzienia pasuje do regularnego potoku i nie potrzebuje dodatkowego stanu ani rejestru tymczasowego. Zaleca również oprogramowaniu, aby utrzymywało najczęstszą ścieżkę jako kod prosty i oczekiwało, że rozgałęzienia wsteczne będą przewidywane jako wykonane, a rozgałęzienia do przodu jako niewykonane, przynajmniej za pierwszym razem, gdy zostaną napotkane.

Rozgałęzienie porównuje dwa rejestry i nie może przyjąć stałej zapisanej w instrukcji, więc forma taka jak beq t0, 5, label nie istnieje. Aby porównać rejestr ze stałą, najpierw załaduj stałą do rejestru za pomocą li, a następnie porównaj dwa rejestry.

li t1, 5
beq t0, t1, done

Wartość 0 nie wymaga ładowania, ponieważ rejestr zero zawsze ją przechowuje.

Częste użycie porównuje rejestr z zero, rejestrem, który zawsze przechowuje 0, aby zapytać, czy wartość osiągnęła zero. To kończy pętle odliczania i sprawdza wyniki. Przykład rozgałęzia się do done, gdy a0 odliczyło do zera. beq i etykiety wystarczą, aby zbudować każdą decyzję i pętlę w programie.

Przykład

beq a0, zero, done   # if a0 == 0, jump to 'done'