在RISC-V上的大端和小端之间转换 [英] Convert between big-endian and little-endian on RISC-V

查看:885
本文介绍了在RISC-V上的大端和小端之间转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在汇编语言级别使用RISC-V中的大端值的最简单方法是什么?即,如何将内存中的大端值加载到寄存器中,如何在本机端(little-endian)中使用寄存器值,然后将其存储回大端中的内存中. 16、32和64位值用于许多网络协议和文件格式.

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 with the register value in native-endian (little-endian), then store it back into memory in big-endian. 16, 32 and 64 bit values are used in many network protocols and file formats.

我找不到字节交换指令(相当于x86上的BSWAP或ARM上的REV)

I couldn't find a byte-swap instruction (equivalent to BSWAP on x86 or REV on ARM) in the manual, nor anything about big-endian loads and stores.

推荐答案

在最新的.该扩展工作组的一些材料草案是在GitHub上收集的.特别是,草稿规范讨论了<可以执行16、32和64位字节交换的c0>指令(通用反向):

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:

此指令提供了一条硬件指令,可以实现所有字节顺序交换,按位反转,短顺序交换,字序交换(RV64),半字节交换,字节中的按位反转等,全部来自一条硬件指令.它通过控制递归树中发生反转的级别,获取一个寄存器值和一个立即数来控制哪个功能发生.

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.

扩展B工作组由于官僚原因于2017年11月解散",然后他们才能最终确定规范.

工作组在2020年再次活跃,将其工作发布在链接的GitHub存储库中.

因此,目前似乎没有比平常的shift-mask-或dance更简单的事情了.我在GCC或clang riscv端口中找不到任何固有的汇编语言bswap.例如,下面是riscv64-linux-gnu-gcc编译器版本8.1.0-12发出的bswapsi2函数(该字节交换32位值)的反汇编:

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

这篇关于在RISC-V上的大端和小端之间转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆