在气体宏中自动生成 xmm 寄存器名称?
Posted
技术标签:
【中文标题】在气体宏中自动生成 xmm 寄存器名称?【英文标题】:Automatically generate xmm register name in a gas macro? 【发布时间】:2011-08-25 02:15:21 【问题描述】:我想写一个gas宏来根据参数n生成包含各种movdqu指令到xmm寄存器的代码。
.macro xxmov n, p1
.if (\n == 1)
xor %eax, %eax
.endif
.if (\n - 1)
xxmov (\n - 1), \p1
.endif
movdqu ((\n - 1)*0x10)(\p1), %xmm0
.endm
xxmov 14, %rsi
编译后,反汇编代码为,
0000000000000000 <.text>:
0: 31 c0 xor %eax,%eax
2: f3 0f 6f 06 movdqu (%rsi),%xmm0
6: f3 0f 6f 46 10 movdqu 0x10(%rsi),%xmm0
b: f3 0f 6f 46 20 movdqu 0x20(%rsi),%xmm0
10: f3 0f 6f 46 30 movdqu 0x30(%rsi),%xmm0
15: f3 0f 6f 46 40 movdqu 0x40(%rsi),%xmm0
1a: f3 0f 6f 46 50 movdqu 0x50(%rsi),%xmm0
1f: f3 0f 6f 46 60 movdqu 0x60(%rsi),%xmm0
24: f3 0f 6f 46 70 movdqu 0x70(%rsi),%xmm0
29: f3 0f 6f 86 80 00 00 movdqu 0x80(%rsi),%xmm0
30: 00
31: f3 0f 6f 86 90 00 00 movdqu 0x90(%rsi),%xmm0
38: 00
39: f3 0f 6f 86 a0 00 00 movdqu 0xa0(%rsi),%xmm0
40: 00
41: f3 0f 6f 86 b0 00 00 movdqu 0xb0(%rsi),%xmm0
48: 00
49: f3 0f 6f 86 c0 00 00 movdqu 0xc0(%rsi),%xmm0
50: 00
51: f3 0f 6f 86 d0 00 00 movdqu 0xd0(%rsi),%xmm0
58: 00
但是,当我在上面的 xxmov 宏中将 %xmm0 替换为 %xmm\n 时,出现编译错误,
$ gcc -c mac.s
mac.s: Assembler messages:
mac.s:17: Error: bad register name `%xmm(((((((((((((14 - 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)'
mac.s:17: Error: bad register name `%xmm((((((((((((14 - 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)'
mac.s:17: Error: bad register name `%xmm(((((((((((14 - 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)'
mac.s:17: Error: bad register name `%xmm((((((((((14 - 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)'
mac.s:17: Error: bad register name `%xmm(((((((((14 - 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)'
mac.s:17: Error: bad register name `%xmm((((((((14 - 1)- 1)- 1)- 1)- 1)- 1)- 1)- 1)'
mac.s:17: Error: bad register name `%xmm(((((((14 - 1)- 1)- 1)- 1)- 1)- 1)- 1)'
mac.s:17: Error: bad register name `%xmm((((((14 - 1)- 1)- 1)- 1)- 1)- 1)'
mac.s:17: Error: bad register name `%xmm(((((14 - 1)- 1)- 1)- 1)- 1)'
mac.s:17: Error: bad register name `%xmm((((14 - 1)- 1)- 1)- 1)'
mac.s:17: Error: bad register name `%xmm(((14 - 1)- 1)- 1)'
mac.s:17: Error: bad register name `%xmm((14 - 1)- 1)'
mac.s:17: Error: bad register name `%xmm(14 - 1)'
那么,无论如何我可以将我的宏操作为 xmm 寄存器名称(从 %xmm0 到 %xmm_n-1)?我试过http://sourceware.org/binutils/docs/as/Macro.html#Macro中提到的\@(%xmm\@)。但是,它并没有很好地工作,因为我想多次使用这个宏,而 \@ 似乎是单调递增的..
【问题讨论】:
【参考方案1】:不如保留一个变量来计数而不是倒数?像这样:
.macro xxmov n, p1, cnt=0
.if (\cnt == 0)
xor %eax, %eax
.endif
.if (\cnt != \n)
movdqu \@*0x10(\p1), %xmm\@
xxmov \n, \p1, (\cnt + 1)
.endif
.endm
xxmov 14, %rsi
生成:
0000000000000000 <.text>:
0: 31 c0 xor %eax,%eax
2: f3 0f 6f 06 movdqu (%rsi),%xmm0
6: f3 0f 6f 4e 10 movdqu 0x10(%rsi),%xmm1
b: f3 0f 6f 56 20 movdqu 0x20(%rsi),%xmm2
10: f3 0f 6f 5e 30 movdqu 0x30(%rsi),%xmm3
15: f3 0f 6f 66 40 movdqu 0x40(%rsi),%xmm4
1a: f3 0f 6f 6e 50 movdqu 0x50(%rsi),%xmm5
1f: f3 0f 6f 76 60 movdqu 0x60(%rsi),%xmm6
24: f3 0f 6f 7e 70 movdqu 0x70(%rsi),%xmm7
29: f3 44 0f 6f 86 80 00 00 00 movdqu 0x80(%rsi),%xmm8
32: f3 44 0f 6f 8e 90 00 00 00 movdqu 0x90(%rsi),%xmm9
3b: f3 44 0f 6f 96 a0 00 00 00 movdqu 0xa0(%rsi),%xmm10
44: f3 44 0f 6f 9e b0 00 00 00 movdqu 0xb0(%rsi),%xmm11
4d: f3 44 0f 6f a6 c0 00 00 00 movdqu 0xc0(%rsi),%xmm12
56: f3 44 0f 6f ae d0 00 00 00 movdqu 0xd0(%rsi),%xmm13
更新:糟糕,这仅适用于文件中的第一个宏使用。如果您需要在同一个文件中多次使用它,看起来使用.altmacro
语法是可行的方法(可以使用.noaltmacro
再次关闭它):
.altmacro
.macro xxmov n, p
.if (\n == 1)
xor %eax, %eax
.endif
.if (\n > 1)
xxmov %(\n - 1), \p
.endif
movdqu (\n - 1)*0x10 (%\p) , %xmm\n
.endm
xxmov 4, rsi
xxmov 14, rsi
【讨论】:
是的,.altmacro 在这里确实有帮助。谢谢。以上是关于在气体宏中自动生成 xmm 寄存器名称?的主要内容,如果未能解决你的问题,请参考以下文章