我如何为 Risc-V(汇编语言)编写旋转操作 我们是否有像 8086 中那样的命令?

How do I write rotation Operation for the Risc-V(Assembly Language) Do we have any command for it like we have have in 8086?

我以前用过8086的汇编语言,8086的旋转操作只是一个命令。但是我在Risc-V汇编语言中找不到轮换操作的具体关键字。

看起来扩展 "B" 最终应该定义这样的指令。

在那之前你必须使用左移和右移来组合它。

这是 MIPS32R2 rotrv 指令的等价物(按变量计数向右循环):

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

你可以在 riscv 上做同样的事情。

RISC-V 基本指令集不包含循环指令。

因此,您必须使用多个基本指令实现旋转(a.k.a。循环移位)例如:

    .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 在零处回绕并且 shift-left-logical (sll) 仅使用低六位 (RV64G) 或五位a4 的 (RV32G) 作为偏移量。

当按立即操作数移位时,GNU as 不会 隐式截断移位量,因此必须显式屏蔽它,例如:

# unsigned long rotl3(unsigned long x);
    .global rotl3
rotl3:
    slli a2, a0,  3
    srli a3, a0, (-3 & 63) # & 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 & 63) # & 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

(RISV-V Bitmanip Extension V0.92,第 2.2.1 节,第 14 页)

当然,截至 2020 年,由于处于草案状态,bitmanip 指令及其编码可能会发生变化,并且软件工具链、模拟器和硬件中对 "B" 扩展的支持尚未广泛提供。