Как правильно повернуть 64-битное значение в ассемблере ARM7? - PullRequest
3 голосов
/ 21 марта 2011

Набор команд ARM7 предлагает эффективные способы правого поворота 32-битных значений на произвольную величину в ассемблере. Для второго операнда операции это даже «бесплатно», указав ror # n в качестве операнда сдвига, но для 64-битных целых чисел прямая поддержка набором инструкций не предоставляется. Помимо особых случаев поворота на 1, 31, 33 или 63 битные позиции (не говоря уже о 0 или 32), я знаю только, как повернуть 64-битное значение, используя четыре инструкции (это довольно легко, поэтому я не пишу это здесь). В четырех особых случаях я могу сократить это до трех инструкций, но я не знаю, как это сделать вообще. Итак, вот мой вопрос:

Учитывая 64-битное значение в двух регистрах, скажем, R0 и R1, можно ли повернуть это значение вправо на n позиций (для произвольных n ) с помощью всего три инструкции ARM7?

Ответы [ 2 ]

2 голосов
/ 29 марта 2011

Если регистр (например, r4) содержит правильную магическую константу (1 сдвинут влево на желаемую величину левого поворота), я думаю, что это можно сделать двумя инструкциями:

  umull r3,r2,r1,r4
  umlal r2,r3,r0,r4

Медленнее, чем использование четырех инструкций с одним циклом, но даже если нужно загрузить r4 с правильной константой, оно все же более компактно, чем методы с четырьмя инструкциями.

1 голос
/ 25 марта 2011

Если есть решение, gcc также не распознает его:

unsigned long long int reg64 = random_value;
unsigned int n = shift_value;
reg64 = (reg64 >> (n%64)) | (reg64 << ((64-n)%64));

приводит к следующему:

п = 1:

MOVS R2, R0, LSR #1
MOV R3, R1, RRX
ORR R2, R2, R1, ASL #31

п = 2-31:

MOV R2, R0, LSR #n
ORR R2, R2, R1, ASL #32-n
MOV R3, R0, ASL #32-n
ORR R3, R3, R1, LSR #n

п = 33-62:

MOV R3, R0, ASL #64-n
ORR R3, R3, R1, LSR #n-32
MOV R2, R0, LSR, #n-32
ORR R2, R2, R1, ASL #64-n

п = 63

ADDS R2, R0, R0
ADC R3, R1, R1
ORR R2, R2, R1, LSR #31
...