Как правильно повернуть 64-разрядное значение в ассемблере ARM7?

StackOverflow https://stackoverflow.com/questions/5379218

Вопрос

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

Учитывая 64-разрядное значение в двух регистрах, скажем, R0 и R1, возможно ли правильно вращать это значение не позиции (для произвольных не) с просто три АРМ7 инструкции?

Это было полезно?

Решение

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

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

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

Другие советы

Если есть решение для этого, GCC также не распознает его:

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

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

n = 1:

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

n = 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

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

n = 63:

ADDS R2, R0, R0
ADC R3, R1, R1
ORR R2, R2, R1, LSR #31
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top