Автоматически генерировать имя регистра xmm в газовом макросе? - PullRequest
6 голосов
/ 25 августа 2011

Я хотел бы написать газовый макрос для генерации кода, содержащего различные инструкции 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

Однако, когда я заменил% xmm0 на% xmm \ n в приведенном выше макросе xxmov, я получил ошибку компиляции,

    $ 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})?Я пытался \ @ (% xmm \ @), упомянутый в http://sourceware.org/binutils/docs/as/Macro.html#Macro. Однако, он не очень хорошо работал, потому что я хотел бы использовать этот макрос несколько раз, в то время как \ @, кажется, монотонно увеличивается ..

1 Ответ

2 голосов
/ 04 сентября 2011

Как насчет того, чтобы вместо обратного отсчета оставить переменную для подсчета?Например:

.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
...