GCC ARM 汇编宏中的表达式
Posted
技术标签:
【中文标题】GCC ARM 汇编宏中的表达式【英文标题】:Expression in GCC ARM assembly macro 【发布时间】:2014-11-08 03:49:48 【问题描述】:我需要涉及许多寄存器的宏,例如:
.macro load128bytes
vld1.8 d0, d1, d2, d3, [r0]!
vld1.8 d4, d5, d6, d7, [r0]!
vld1.8 d8, d9, d10, d11, [r0]!
vld1.8 d12, d13, d14, d15, [r0]!
.endm
如您所见,寄存器是连续的。但是,我想将起始寄存器的数量作为参数传递,例如:
.macro load128bytes srn
vld1.8 d\srn, d\srn+1, d\srn+2, d\srn+3, [r0]!
vld1.8 d\srn+4, d\srn+5, d\srn+6, d\srn+7, [r0]!
vld1.8 d\srn+8, d\srn+9, d\srn+10, d\srn+11, [r0]!
vld1.8 d\srn+12, d\srn+13, d\srn+14, d\srn+15, [r0]!
.endm
当然,上面的方法是行不通的。汇编器将它们解释为:d0, d0+1, d0+2, d0+3 而不是 d0, d1, d2, d3 当 srn 为 0 时我想要它们。
我在网上搜索了一个可以解决此问题的示例:
.macro sum from=0, to=5
.long \from
.if \to-\from
sum "(\from+1)",\to
.endif
.endm
虽然上面的例子运行良好,但它并没有帮助解决我的问题:
.macro test srn0
vld1.8 d"(\srn0)", d"(\srn0+1)", [r0]
.endm
上述构建会导致错误消息:Neon double or quad precision register expected -- `vld1.8 d"0",d"0+1",[r0]'
有什么想法吗?每次传递多达 16 个寄存器真的很令人沮丧,更糟糕的是,它使我的代码容易出错。
提前致谢。
【问题讨论】:
【参考方案1】:sum 示例之所以有效,是因为它给出了以下输出:
.long 0
.long (0+1)
.long ((0+1)+1)
.long (((0+1)+1)+1)
.long ((((0+1)+1)+1)+1)
.long (((((0+1)+1)+1)+1)+1)
因此,在宏扩展之后,汇编器在它期望表达式的地方看到表达式,并计算它们。您需要的技巧是让它在它不期望表达式的地方评估表达式,并在程序集传递之前这样做。 alternate macro mode 和 CPP 样式的宏链接(为清晰起见,使用较小的示例)来提供帮助:
.macro _load32bytes base r0 r1 r2 r3
vld1.8 d\r0, d\r1, d\r2, d\r3, [\base]!
.endm
.macro load32bytes srn
.altmacro
_load32bytes r0, %(\srn), %(\srn+1), %(\srn+2), %(\srn+3)
.endm
%
运算符允许在宏扩展期间任意将表达式评估为字符串 - 我似乎无法说服它在单个宏中工作,但链接可以完成这项工作:
$ arm-linux-gnueabihf-as -alm -mfpu=neon test.s
ARM GAS test.s page 1
1 .macro _load32bytes base r0 r1 r2 r3
2 vld1.8 d\r0, d\r1, d\r2, d\r3, [\base]!
3 .endm
4
5 .macro load32bytes srn
6 .altmacro
7 _load32bytes r0, %(\srn), %(\srn+1), %(\srn+2), %(\srn+3)
8 .endm
9
10 load32bytes 0
10 > .altmacro
10 > _load32bytes r0,%(0),%(0+1),%(0+2),%(0+3)
10 0000 0D0220F4 >> vld1.8 d0,d1,d2,d3,[r0]!
11 load32bytes 3
11 > .altmacro
11 > _load32bytes r0,%(3),%(3+1),%(3+2),%(3+3)
11 0004 0D3220F4 >> vld1.8 d3,d4,d5,d6,[r0]!
12
【讨论】:
像魅力一样工作!非常感谢你。顺便说一句,我目前正在从事一个大型开源项目,该项目由纯手工制作的 NEON 组装例程和一本关于 ARM 优化的电子书组成。他们完成后我会告诉你的。当然,您将收到该电子书的免费“副本”。 :)以上是关于GCC ARM 汇编宏中的表达式的主要内容,如果未能解决你的问题,请参考以下文章
GCC 内联汇编错误:表达式后出现垃圾 `(%ebp)+4'