32-битная инструкция PPC rlwinm

У меня небольшие проблемы с пониманием инструкции по сборке rlwinm PPC (повернуть левое слово сразу, затем И с маской).

Я пытаюсь отменить эту часть функции

rlwinm r3, r3, 0, 28, 28

Я уже знаю, что такое r3. r3 в данном случае представляет собой 4-байтовое целое число, но я точно не знаю, что с ним делает эта инструкция rlwinm.

Кстати, это на 32-битной машине.


person thehaxdev    schedule 22.10.2017    source источник
comment
Вы смотрели ссылку на набор инструкций? Первый ноль — это сдвиг, а два операнда 28 — это начало и конец маски (которая представляет собой последовательность из 1 битов, поэтому явно не значение 28).   -  person Jester    schedule 22.10.2017
comment
справочник по набору инструкций PowerPC   -  person Bob Jarvis - Reinstate Monica    schedule 22.10.2017


Ответы (2)


Ваше понимание не совсем верное. Согласно ссылке IBM в этой инструкции форма, которую вы видите:

rlwinm <target=r3>, <source=r3>, <shift=0>, <begin-mask=28>, <end-mask=28> 

Следовательно, никакого фактического сдвига не происходит. И фактическая маска, используемая для операции AND, создается из позиций begin и end маски, она не задается как явный аргумент(a).

В этом случае, поскольку обе позиции равны 28, маска представляет собой просто один бит, как на связанной странице (слегка перефразируя):

Если значение begin-mask меньше, чем значение end-mask плюс один, биты маски между начальной и конечной точками включительно устанавливаются в единицы. Все остальные биты устанавливаются в нули.

Таким образом, инструкция, которую вы видите, представляет собой не что иное, как одну операцию AND.


(a) Существует существует форма, которая позволяет указать фактическую маску (при условии, что она состоит из смежных однобитовых битов), но это четыре -аргументная версия и на самом деле просто синтаксический сахар, который ассемблер может превратить в пятиаргументную.

person paxdiablo    schedule 22.10.2017
comment
Обратите внимание, что PowerPC считает биты, начиная с MSB=0, в отличие от других архитектур. Таким образом, маска AND равна 1U<<(31-28) в нотации C. - person Peter Cordes; 30.04.2018

Ответ @paxdiablo правильный, но для добавления контекста:

Различные инструкции r* (rlwinm, rlwimi и т. д.) предназначены для извлечения битовых полей, размер которых известен во время компиляции, например, битовых полей структуры C, или даже просто для разбиения слова на байты (что может быть быстрее с одним lw и четырьмя rlwinm). инструкции, чем несколько отдельных lbzus).

lw r4, r3 ; load the word at the address pointed at by r3
rlwinm r5, r4, 8, 24, 31 ; first byte in r5
rlwinm r6, r4, 16, 24, 31 ; second byte in r6
rlwinm r7, r4, 24, 24, 31 ; third byte in r7
rlwinm r8, r4, 0, 24, 31 ; fourth byte in r8, identical to andi r8, r4, 255

Инструкции rlwinm также можно использовать, как в данном случае, как специальную форму andi для смежных наборов битов. Поскольку инструкции в PowerPC всегда являются 32-битными, инструкции, принимающие немедленные значения, имеют только 16 бит для хранения этих значений, поэтому, если вы хотите замаскировать набор битов, которые пересекают верхнюю/младшую границу полуслова, скажем, от 23 до 8, вам нужно использовать несколько операций.

lis r4, r4, 0x00ff ; first set bits 23 to 16 of the mask
ori r4, r4, 0xff00 ; then bits bits 15 to 8
and r3, r3, r4 ; then perform the actual masking 

Однако с помощью инструкций rlwinm мы можем выполнить ту же операцию в одной инструкции:

rlwinm r3, r3, 0, 8, 23

В вашем случае значение, вероятно, содержит флаги для чего-то, и эта инструкция извлекает один из них. Следующая инструкция, вероятно, является условным переходом на r3.

ETA: Питер Кордес исправил некоторые мои ошибки, за что я ему благодарен, и добавил, что, вероятно, в данном случае нет необходимости использовать rlwinm, и что это может быть просто особенность компилятора, из-за которой вместо этого генерируется эта инструкция andi.

person Evan    schedule 30.04.2018
comment
Кроме того, PowerPC считает биты, начиная с MSB=0, поэтому для 32-разрядной машины используется маска 1<<(31-28). В 64-битном режиме бит 28 будет в старшей половине 64-битного регистра, поэтому PowerPC имеет разные версии этих инструкций для 64-битного режима. gcc, кажется, всегда использует rlwinm, когда это возможно, используя andi только тогда, когда маска не является непрерывной группой 1-битов. - person Peter Cordes; 30.04.2018
comment
Спасибо! на самом деле это было какое-то время, поэтому я ценю, что его проверили. - person Evan; 30.04.2018
comment
Если у вас есть время, я настоятельно рекомендую вернуться и переписать части ответа, которые были неправильными, и добавить примечание о том, как биты чисел PowerPC. Вы хотите, чтобы ответ был правильным в первую очередь, а не неправильным + исправления. Тогда это было бы достойно плюса, ИМО. Каждый может просмотреть историю редактирования, если захочет, и цель SO состоит в том, чтобы текущая версия ответа была как можно лучше. - person Peter Cordes; 30.04.2018