Assembly ARM:将包含32位值一半的两个寄存器合并到目标寄存器中的最佳方法

Assembly ARM:将包含32位值一半的两个寄存器合并到目标寄存器中的最佳方法,assembly,arm,Assembly,Arm,假设我在r0、r1和r2中有三个uint32_t值;假设我有一个常量shift在[0,32] 下面是我需要执行的C代码: uint32_t rx = (r0 >> shift) | (r1 << (32 - shift)); uint32_t ry = (r1 >> shift) | (r2 << (32 - shift)); 如果移位是8位还是24位呢? 基本上,我有一个未对齐的指针,我需要从这个未对齐的指针中读取单词。首先,我想清除两个最低有

假设我在
r0
r1
r2
中有三个uint32_t值;假设我有一个常量
shift
[0,32]

下面是我需要执行的C代码:

uint32_t rx = (r0 >> shift) | (r1 << (32 - shift));
uint32_t ry = (r1 >> shift) | (r2 << (32 - shift));
如果移位是8位还是24位呢? 基本上,我有一个未对齐的指针,我需要从这个未对齐的指针中读取单词。首先,我想清除两个最低有效位(使其对齐4字节),然后使用该指针读取单词,并执行一些洗牌操作,以按顺序获得寄存器中所需的内容


注意:我不需要解决办法或其他建议。我需要从未对齐的指针获取单词。我无法修改U或A位,未对齐的读取会使应用程序崩溃。

我认为这种方法应该可以工作,尽管我没有测试过:

BFI  rx, r0, #8, #24
BFI  ry, r1, #8, #24
UBFX r1, r1, #24, #8
BFI  rx, r1, #0, #8
UBFX r2, r2, #24, #8
BFI  ry, r2, #0, #8

我不认为只有一两条说明就可以做到。如果你更喜欢的话,UBFX可以换成右移

请注意,一些ARM体系结构确实支持未对齐的负载

编辑:这一直困扰着我。必须有更好的方法,我想我现在找到了:

@ shift is one of {8, 16, 24}
lsr     rx, r0, #\shift
orr     rx, rx, r1, lsl #32-\shift
lsr     ry, r1, #\shift
orr     ry, ry, r2, lsl #32-\shift

r0
可以用作目标寄存器,代替
rx
,与
r1
/
ry

相同。“我不需要变通办法或其他建议”仅供参考,这是非常粗鲁的。是的,我知道你们不需要这个建议:)去读一读XY问题。你们可能会说我有XY问题,但我不想知道任何关于Y的解决方案。清楚的我说得很清楚,因为我知道我可能会得到一些无用的建议,比如arm可以进行不对齐的阅读等等。我知道这与我的要求无关。你没有解释为什么你需要“两个指令”。您没有提到您的实际硬件以及无法启用未对齐读取的原因。你没有说为什么memcpy不适合你。等等仅仅因为你认为这是解决整体问题的方法,并不意味着它是唯一的解决方案。我对armv6执行16x16字节SAD和未对齐读取,但我需要支持特殊的模拟器,这是一堆垃圾,所以唯一的方法是进行未对齐的读取,并将这些内容合并到寄存器中,这样我就可以使用USADA8指令。只是因为这一个操作代码,没有其他解决方案能比这更好。顺便说一句,这将是XY的问题:我应该问如何使arm的垃圾仿真器正常工作,但他们对此保持沉默。到目前为止,所有C++工具都像是从MSS中提取出来的,就像是2个单词(显然不可能在两个指令中得到2个单词),这就是我一直在寻找的。我就是不明白:谁在arm上写的那些毫无用处的文件。他们的手册应该与一本书同时阅读?我无法得到BFI的确切功能,唯一的方法是测试并查看结果。在android上,我无法测试,迟钝的构建系统使其过于模糊,无法设置正确的编译器/汇编程序标志。令人惊讶的是,使用两个BFI指令组合成一个单词是不可能的。原因是r1的高位不能放入目标字的最低字节。似乎每个加载需要3条指令,或者需要一些其他操作码哦!我应该发现的。当然,您也需要换档,但仅适用于r1和r2,而不适用于r0:(好的,我刚刚编辑了我的答案,为高阶位添加了位域提取。我认为如果我切换到big-endian读取,原始解决方案可能会起作用。我需要重新调整字节以能够使用USADA8,并且使用big-endian或little-endian内存访问没有区别。我将测试它是否有帮助。否则,我认为它会更好。)使用定期轮班制,每个单词3次。
BFI  rx, r0, #24, #8
BFI  ry, r1, #24, #8
UBFX r1, r1, #8, #24
BFI  rx, r1, #0, #24
UBFX r2, r2, #8, #24
BFI  ry, r2, #0, #24
@ shift is one of {8, 16, 24}
lsr     rx, r0, #\shift
orr     rx, rx, r1, lsl #32-\shift
lsr     ry, r1, #\shift
orr     ry, ry, r2, lsl #32-\shift