Есть ли способ выполнить арифметическое смещение вправо, используя только xorq, andq, addq, iaddq, & subq? - PullRequest
0 голосов
/ 19 ноября 2018

Я нахожусь в гипотетической архитектуре, которая имеет только эти операции (Y86). Никакого арифметического сдвига вправо не существует. По сути, я пытаюсь захватить самый верхний бит, чтобы определить, является ли число отрицательным, и если это так, добавить его в регистр результатов, rax.

Edit:

Извините все, я забыл указать, я стараюсь избегать условных веток, чтобы увидеть, если это улучшает эффективность. В версии, в которой я нахожусь, нет cmov.

Самое дальнее, что я получил:

andq $0x10000000, elem
subq $0x01111111, elem
addq elem, %rax

Однако для результата 0 это не сработает.

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Если Y86 позволяет MOVQ получать доступ к памяти, которая не выровнена по QWORD, то это можно сделать. Но я сомневаюсь, что он будет работать лучше, чем условная ветвь.

Хитрость заключается в том, чтобы записать число в память, затем прочитайте его снова с адреса, который немного «выключен». Это эффективно сдвигает биты на кратное 8. Объедините это с addq, чтобы сдвинуть биты 1 влево.

Обратите внимание, что это в значительной степени зависит от последовательности архитектуры процессора. Следующий пример основан на порядке байтов (в стиле Intel). На старшем порядке смещения должны быть скорректированы.

(Если вы предпочитаете синтаксис AT & T, измените операнды и удалите скобки.)

movq rbx,number         ; sign bit is bit 63 of rbx
movq [address],rbx      ; sign bit is most significant bit of the byte at [address+7]
movq rbx,[address+4]    ; sign bit is bit 31 of rbx
addq rbx,rbx            ; sign bit is bit 32 of rbx
movq [address],bx       ; sign bit is least significant bit of the byte at [address+4]
movq rbx,[address+4]    ; sign bit is bit 0 of rbx
andq rbx,1              ; rbx = 0 for positive number, rbx = 1 for negative number
addq ax,bx
0 голосов
/ 19 ноября 2018

Предполагая, что вы можете использовать цикл и условную ветвь:

    mov result, 0
    mov lead, 2
    mov follow, 1
1:
    mov tmp, n
    and tmp, lead
    jz 2f
    add result, follow
2:
    add follow, follow
    add lead, lead
    jnz 1b

Переменные tmp, lead и follow должны быть в регистрах.результат может быть либо в регистре, либо в памяти.

...