6

パラメータ n に応じて xmm レジスタへのさまざまな movdqu 命令を含むコードを生成するガス マクロを作成したいと考えています。

    .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 に答える