Reputation: 813
I have worked with assembly language of 8086 previously, rotation operation in 8086 was just a command. But I can't find a specific keyword for rotation operation in Risc-V assembly language.
Upvotes: 1
Views: 2375
Reputation: 39017
The RISC-V base instruction set doesn't include rotate instructions.
Thus, you have to implement rotation (a.k.a. cyclic shift) with multiple basic instructions e.g.:
.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
Note that sub a4, zero, a1
wraps around at zero and shift-left-logical (sll
) only uses the lower six (RV64G) or five bits (RV32G) of a4
as shift amount.
When shifting by an immediate operand, GNU as
does not implicitly truncate the shift-amount, thus one has to explicitly mask it, e.g.:
# 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
The RISC-V Bitmanip Extension "B" draft specification does include several additional shift and shuffle instruction including left and right rotate:
# 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, Section 2.2.1, page 14)
Of course, as of 2020, because of the draft status, bitmanip instructions and their encodings may change and support for the "B" extension in software toolchains, simulator and hardware isn't widely available.
Upvotes: 2
Reputation: 62048
It looks like extension "B" should define such an instruction eventually.
Until then you have to compose it using left and right shifts.
Here's an equivalent of the MIPS32R2 rotrv instruction (rotate right by variable count):
rotrv:
subu neg_count, zero, count
srlv tmp1, src, count
sllv tmp2, src, neg_count
or dst, tmp1, tmp2
You can do the same on riscv.
Upvotes: 2