Как мне написать операцию поворота для Risc-V (язык ассемблера) Есть ли у нас для этого какая-либо команда, как у нас в 8086?

#assembly #riscv

#сборка #riscv

Вопрос:

Ранее я работал с языком ассемблера 8086, операция поворота в 8086 была просто командой. Но я не могу найти конкретное ключевое слово для операции поворота на языке ассемблера Risc-V.

Комментарии:

1. Расширение Bitmanip RISC-V вращает

Ответ №1:

Похоже, что расширение «B» должно в конечном итоге определить такую инструкцию.

До тех пор вам придется составлять ее, используя сдвиги влево и вправо.

Вот эквивалент инструкции MIPS32R2 rotrv (повернуть вправо по количеству переменных):

 rotrv:
    subu    neg_count, zero, count
    srlv    tmp1, src, count
    sllv    tmp2, src, neg_count
    or      dst, tmp1, tmp2
  

Вы можете сделать то же самое на riscv.

Ответ №2:

Базовый набор команд RISC-V не включает в себя инструкции поворота.

Таким образом, вы должны реализовать поворот (он же циклический сдвиг) с несколькими базовыми инструкциями, например:

     .text
    .balign 4
# unsigned long rotl(unsigned long x, unsigned long amnt);
    .global rotl
rotl:
    sll  a2,   a0, a1
    sub  a4, zero, a1
    srl  a3,   a0, a4
    or   a0,   a2, a3
    ret
# unsigned long rotr(unsigned long x, unsigned long amnt);
    .global rotr
rotr:
    srl  a2,   a0, a1
    sub  a4, zero, a1
    sll  a3,   a0, a4
    or   a0,   a2, a3
    ret
  

Обратите внимание, что sub a4, zero, a1 выполняется обтекание с нулевым значением, а логический ( sll ) сдвиг влево использует только младшие шесть (RV64G) или пять битов (RV32G) a4 в качестве величины сдвига.

При сдвиге с помощью непосредственного операнда GNU as не неявно усекает величину сдвига, поэтому приходится явно маскировать это, например:

 # unsigned long rotl3(unsigned long x);
    .global rotl3
rotl3:
    slli a2, a0,  3
    srli a3, a0, (-3 amp; 63) # amp; 31 for RV32G
    or   a0, a2, a3
    ret
# unsigned long rotr3(unsigned long x);
    .global rotr3
rotr3:
    srli a2, a0,  3 
    slli a3, a0, (-3 amp; 63) # amp; 31 for RV32G
    or   a0, a2, a3
    ret     
    .global rotl
  

RISC-V Bitmanip Extension «B» черновик спецификации действительно включает в себя несколько дополнительных команд сдвига и перетасовки, включая поворот влево и вправо:

 # RV32, RV64:
ror   rd, rs1, rs2
rol   rd, rs1, rs2
rori  rd, rs1, imm

# RV64 only:
rorw  rd, rs1, rs2
rolw  rd, rs1, rs2
roriw rd, rs1, imm
  

(Расширение Bitmanip RISV-V версии 0.92, раздел 2.2.1, страница 14)

Конечно, с 2020 года из-за статуса черновика инструкции bitmanip и их кодировки могут измениться, а поддержка расширения «B» в программных наборах инструментов, симуляторе и аппаратном обеспечении не является широко доступной.

Комментарии:

1. Что произойдет, если вы не замаскируете немедленное? Получается ли в итоге машинный код, который смещает все биты, рассматривая это как большое количество? (например, x86 маскирует количество мгновенных сдвигов так же, как регистры, поэтому вам не нужно этого делать.)

2. @PeterCordes нет, но GNU as завершает работу с: Error: Improper shift amount (18446744073709551613)

3. Ах, итак, проблема в том, что она не будет усекать величину сдвига, чтобы соответствовать машинному кодированию. Спасибо.