我正在尝试使用内联汇编创建ldm
(resp.stm
)指令,但是在表达操作数方面存在问题(尤其是:它们的顺序).
一件微不足道的事
void *ptr; unsigned int a; unsigned int b; __asm__("ldm %0!,{%1,%2}" : "+&r"(ptr), "=r"(a), "=r"(b));
不工作,因为它可能把a
到r1
和b
成r0
:
ldm ip!, {r1, r0}
ldm
期望寄存器按升序排列(因为它们在位域中编码)所以我需要一种方法来说明用于的寄存器a
低于此b
.
一个简单的方法是固定分配寄存器:
register unsigned int a asm("r0"); register unsigned int b asm("r1"); __asm__("ldm %0!,{%1,%2}" : "+&r"(ptr), "=r"(a), "=r"(b));
但这会消除很多灵活性,并可能使生成的代码不是最佳的.
gcc(4.8)是否支持特殊约束ldm/stm
?或者,有更好的方法来解决这个问题(例如某些__builtin
功能)?
因为有建议使用"更高级别"的结构......我想要解决的问题是32位32位字的打包(例如输入是8个字,输出是5个字).伪代码是
asm("ldm %[in]!,{ %[a],%[b],%[c],%[d] }" ...) asm("ldm %[in]!,{ %[e],%[f],%[g],%[h] }" ...) /* splitting of ldm generates better code; gcc gets out of registers else */ /* do some arithmetic on a - h */ asm volatile("stm %[out]!,{ %[a],%[b],%[c],%[d],%[e] }" ...)
速度在这里ldm
很重要,速度比快50%ldr
.算术是棘手的,因为gcc
生成比我更好的代码;)我想在内联汇编中解决它,给出一些关于优化内存访问的提示.