Ответ @paxdiablo правильный, но для добавления контекста:
Различные инструкции r*
(rlwinm, rlwimi и т. д.) предназначены для извлечения битовых полей, размер которых известен во время компиляции, например, битовых полей структуры C, или даже просто для разбиения слова на байты (что может быть быстрее с одним lw
и четырьмя rlwinm
). инструкции, чем несколько отдельных lbzu
s).
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
28
— это начало и конец маски (которая представляет собой последовательность из1
битов, поэтому явно не значение28
). - person Jester   schedule 22.10.2017