Convert between big-endian and little-endian on RISC-V

前端 未结 4 1481
-上瘾入骨i
-上瘾入骨i 2021-01-14 07:45

What is the simplest way to work with big-endian values in RISC-V at the assembly language level? That is, how to load a big-endian value from memory into a register, work w

4条回答
  •  佛祖请我去吃肉
    2021-01-14 08:21

    There is no mention of a byte-swap instruction in the latest RISC-V User-Level ISA Manual (version 2.1). However, the manual has a placeholder for “B” Standard Extension for Bit Manipulation. Some draft materials from that extension's working group are collected on GitHub. In particular, the draft specification talks about a grev instruction (generalized reverse) that can do 16, 32 and 64-bit byte-swaps:

    This instruction provides a single hardware instruction that can implement all of byte-order swap, bitwise reversal, short-order-swap, word-order-swap (RV64), nibble-order swap, bitwise reversal in a byte, etc, all from a single hardware instruction. It takes in a single register value and an immediate that controls which function occurs, through controlling the levels in the recursive tree at which reversals occur.

    The extension B working group was "dissolved for bureaucratic reasons in November 2017" before they could finalize the spec.

    In 2020 the working group is active again, posting their work at the linked GitHub repo.

    As a result, there currently doesn't seem to be anything simpler than doing the usual shift-mask-or dance. I couldn't find any assembly language bswap intrinsic in the GCC or clang riscv ports. As an example, here's a disassembly of the bswapsi2 function (which byte-swaps a 32-bit value) emitted by the riscv64-linux-gnu-gcc compiler version 8.1.0-12:

    000000000000068a <__bswapsi2>:
     68a:   0185169b                slliw   a3,a0,0x18
     68e:   0185579b                srliw   a5,a0,0x18
     692:   8fd5                    or      a5,a5,a3
     694:   66c1                    lui     a3,0x10
     696:   4085571b                sraiw   a4,a0,0x8
     69a:   f0068693                addi    a3,a3,-256 # ff00 <__global_pointer$+0xd6a8>
     69e:   8f75                    and     a4,a4,a3
     6a0:   8fd9                    or      a5,a5,a4
     6a2:   0085151b                slliw   a0,a0,0x8
     6a6:   00ff0737                lui     a4,0xff0
     6aa:   8d79                    and     a0,a0,a4
     6ac:   8d5d                    or      a0,a0,a5
     6ae:   2501                    sext.w  a0,a0
     6b0:   8082                    ret
    

提交回复
热议问题