问题是在C函数内部我有一个内联汇编。 像
这样的东西 ldr r7, =0xdeadbeef
svc 0
如果没有显式创建文字池(就是这种情况),汇编程序 在翻译单元的末尾创建一个。通常这很好,但如果 翻译单元结果真的很大,这不起作用,因为 文字池离ldr指令太远了。
所以,我想知道处理这个问题的最佳方法是什么。最明显的方式是 在内联程序集中手动创建文字池:
ldr r7, =0xdeadbeef
svc 0
b 1f
.ltorg
1:
或者
ldr r7, 1f
svc 0
b 2f
1:
.word 0xdeadbeef
2:
不幸的是,由于冗余分支,这导致了次优代码 指令。我不希望汇编程序能够聪明地找到合适的东西 在函数内部放置常量池。我想做的是 在函数末尾创建一个常量池。有没有办法告诉 编译器(gcc)在函数的末尾创建一个文字池?
PS 我最终使用movw/movt
对而不是常量池。虽然,
首先,movw / movt解决方案的可移植性略低于文字池,
其次,我只是想知道是否可以在内联汇编中使用常量池
既可靠又有效。
更新: 那么,处理问题的最佳方法是什么?
强制工具链在可以放置的函数之后创建一个常量池 该函数在单独的代码部分中。它的工作原理是因为在翻译单元汇编器生成的最后 为每个部分分隔常量池。
实际上,最佳方法是避免将常量加载到寄存器中 内联装配。让编译器这样做会更好。就我而言,我 最终写了一个类似于
的代码register int var asm("r7") = 0xdeadbeef;
asm volatile("svc 0\n" :: "r" (var));
答案 0 :(得分:3)
您可以使用-ffunction-sections
并按照query on -ffunction-section
使用ld --gc-sections
删除未使用的代码。
有明显的分割文件。
应该有效的解决方案是使用带有naked
注释的unused
函数,因为它从未被调用过。在这里放置一个.ltorg
,并将两个函数放在一个特殊的部分;例如.text.ltorg_kludge
。链接描述文件应使用.text*
,并将相同子部分中的函数放在一起。在某些方面,这就像拆分文件一样,因为编译器会尝试内联static
函数。
您可以依赖源代码中遇到的编译器发射函数,而不需要特殊的部分。但是,我不确定这是标准还是发生的立场。编译器可以通过在调用层次结构的某些DAG排序中发出函数来更好地进行优化。
除此之外:由于缓存效应,movw
/ movt
效率更高。它也适用于ARMv6及以上的Thumb2代码。我不认为可移植性是一个大问题(因为内联汇编程序是不可移植的,你可能更喜欢性能而不是可移植性),但这个问题与ARMv4 / 5用户有关。
R
常量池中的项目
但是,sample with gcc-4.8会出现错误无法约束。使用 C 等替代字母也会显示相同的错误消息。检查source contraints.md似乎表明 R 约束是仅限文档的功能。不幸的是,因为它听起来是为解决这个问题而建的。
可以让编译器加载该值,但这可能是次优的,具体取决于inline
汇编程序。例如,
asm(" add %0, %0, %1\n" : "+r" (0xdeadbeef) : "r" (0xbaddeed0));