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
Unlike x86, RISC-V doesn't have something like movbe (which can load and byte-swap in one instruction).
Thus, on RISC-V you load/store as usual and after/before the load/store you have to swap the bytes with extra instructions.
The RISC-V "B" (Bitmanip) extension (version 0.92) contains generalized bit reverse instructions (grev, grevi) and several pseudo-instructions that you could use for byte swapping:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
RISC-V ARM X86 Comment
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
rev RBIT ☐ bit reverse
rev8.h REV16 ☐ byte-reverse half-word (lower 16 bit)
rev8.w REV32 ☐ byte-reverse word (lower 32 bit)
rev8 REV BSWAP byte-reverse whole register
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
(Table based on Table 2.5, RISC-V Bitmanip Extension V0.92, page 18)
As of 2020-03, the "B" extension has draft status, thus support in hardware and emulators is limited.
Without the "B" extension you have to implement the byte swapping with several base instructions. See for example page 16 in the "B" specification or look at the disassembled code of the __builtin_bswap16, __builtin_bswap32 and __builtin_bswap64 gcc/clang intrinsics.