2014-11-08 2 views
2

Я нуждается макросов с большим количеством регистров, связанных, например:Экспрессия в GCC ARM сборки макросъемки

.macro load128bytes 
    vld1.8 {d0, d1, d2, d3}, [r0]! 
    vld1.8 {d4, d5, d6, d7}, [r0]! 
    vld1.8 {d8, d9, d10, d11}, [r0]! 
    vld1.8 {d12, d13, d14, d15}, [r0]! 
.endm 

Как вы можете видеть, регистры являются последовательными. Тем не менее, я хочу передать номер стартового регистра в качестве аргумента, как:

.macro load128bytes srn 
    vld1.8 {d\srn, d\srn+1, d\srn+2, d\srn+3}, [r0]! 
    vld1.8 {d\srn+4, d\srn+5, d\srn+6, d\srn+7}, [r0]! 
    vld1.8 {d\srn+8, d\srn+9, d\srn+10, d\srn+11}, [r0]! 
    vld1.8 {d\srn+12, d\srn+13, d\srn+14, d\srn+15}, [r0]! 
.endm 

И, конечно же, выше, не работает. Ассемблер интерпретирует их как: d0, d0 + 1, d0 + 2, d0 + 3 вместо d0, d1, d2, d3, что я им намереваюсь, когда srn равно 0.

Я искал в Интернете и нашел пример, который мог бы решить эту проблему:

.macro sum from=0, to=5 
    .long \from 
    .if  \to-\from 
    sum  "(\from+1)",\to 
    .endif 
.endm 

Хотя приведенный выше пример работает нормально, это не помогло решить мои проблемы:

.macro test srn0 
    vld1.8  {d"(\srn0)", d"(\srn0+1)"}, [r0] 
.endm 

здания выше, приводит к сообщению об ошибке: Neon двойной или четверной точности регистр ожидается - `vld1.8 {d" 0 ", d" 0 + 1 "}, [r0] '

Любые идеи? Очень сложно каждый раз переходить до шестнадцати регистров, и, что еще хуже, это делает мой код подверженным ошибкам.

Заранее спасибо.

ответ

2

Пример сумма работ becuase дает этот вывод:

.long 0 
.long (0+1) 
.long ((0+1)+1) 
.long (((0+1)+1)+1) 
.long ((((0+1)+1)+1)+1) 
.long (((((0+1)+1)+1)+1)+1) 

Таким образом, после того, как макроподстановкам ассемблер видит выражения, где он ожидает выражения, и оценивает их. Трюк вам нужен, чтобы получить его для оценки выражений, где не ожидать выражения, и сделать это до пропуск сбоку. На помощь приходит alternate macro mode и CPP стиле макро СЦЕПЛЕНИЕ (меньший пример для наглядности):

.macro _load32bytes base r0 r1 r2 r3 
    vld1.8 {d\r0, d\r1, d\r2, d\r3}, [\base]! 
.endm 

.macro load32bytes srn 
.altmacro 
    _load32bytes r0, %(\srn), %(\srn+1), %(\srn+2), %(\srn+3) 
.endm 

Оператор % позволяет оценить выражение в строку произвольно во макроподстановкам - я никак не мог убедить его работать в пределах одного макроса, но цепочки выполняет работу:

$ arm-linux-gnueabihf-as -alm -mfpu=neon test.s 
ARM GAS test.s       page 1 


    1     .macro _load32bytes base r0 r1 r2 r3 
    2      vld1.8 {d\r0, d\r1, d\r2, d\r3}, [\base]! 
    3     .endm 
    4 
    5     .macro load32bytes srn 
    6     .altmacro 
    7      _load32bytes r0, %(\srn), %(\srn+1), %(\srn+2), %(\srn+3) 
    8     .endm 
    9 
    10     load32bytes 0 
    10     > .altmacro 
    10     > _load32bytes r0,%(0),%(0+1),%(0+2),%(0+3) 
    10 0000 0D0220F4  >> vld1.8 {d0,d1,d2,d3},[r0]! 
    11     load32bytes 3 
    11     > .altmacro 
    11     > _load32bytes r0,%(3),%(3+1),%(3+2),%(3+3) 
    11 0004 0D3220F4  >> vld1.8 {d3,d4,d5,d6},[r0]! 
    12 
+0

Работает как очарование! Большое спасибо. BTW, я в настоящее время работаю над большим проектом с открытым исходным кодом, состоящим из простых ручных программ сборок NEON и электронной книги по оптимизации ARM. Я сообщу вам, как только они закончатся. И, конечно же, вы получите бесплатную «копию» этой электронной книги. :) –

Смежные вопросы