6

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

4

1 回答 1

2

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

.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
于 2011-09-04T16:36:13.727 回答