在gas宏中自动生成xmm寄存器名称?

发布于 2024-12-01 19:18:40 字数 2984 浏览 0 评论 0原文

我想编写一个gas宏来生成包含各种movdqu指令的代码到xmm寄存器,具体取决于参数n。

    .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 中提到的 \@ (%xmm\@)。 org/binutils/docs/as/Macro.html#Macro。但是,它工作得不太好,因为我想多次使用这个宏,而 \@ 似乎是单调递增的。

I would like to write a gas macro to generate code containing various movdqu instructions to xmm register depending on the parameter n.

    .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

Once compiled, the disassembled code is,

    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

However, when I replaced %xmm0 with %xmm\n in the above xxmov macro, I got compiling error,

    $ 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)'

So, it there anyway I can manipulate my macro to xmm register name (from %xmm0 to %xmm_{n-1})? I have tried \@ (%xmm\@) mentioned in http://sourceware.org/binutils/docs/as/Macro.html#Macro. However, it didn't work very well because I would like to use this macro multiple time, while \@ seems to be monotonically increasing..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

很快妥协 2024-12-08 19:18:40

与其倒数,不如保留一个变量来向上计数怎么样?像这样:

.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

How about rather than counting down you keep a variable to count up? Like this:

.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

Which generates:

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

Update: Oops, that only works for the first macro usage in the file. If you need to use it more than once in the same file, it looks like using the .altmacro syntax is the way to go (it can be turned off again with .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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文