Shifts

From ARMwiki
(Difference between revisions)
Jump to: navigation, search
(Added diagrams.)
 
(Added RLX via ADC note, and information on I bit.)
 
(One intermediate revision by one user not shown)
Line 1: Line 1:
 +
There are eleven types of shift possible in Data Processing instructions where a "shift" is available. This document describes them.
 +
 +
The '''I''' bit, bit 25, of the instruction determines if the shift type is ''Immediate'' or ''Register''. With this selection made, the lower twelve bits of the instruction define the shift.
 +
 +
===Non shifts===
 +
There are two ''non-shift'' types - the ''immediate'' and a ''register'' reference.
 +
 +
'''Immediate''' values are values that are directly encoded into the instruction, such as:
 +
  ADD  R0, R1, #123
 +
There is, however, a slight complication in that not all values can be represented. The immediate works by optionally shifting an eight bit value. Thus, any value up to &FF is valid. Likewise, it is possible to shift that around, so &F000000F is valid, as is &000AD000. However &00000123 is not (for &123 cannot be described by rotating an eight bit value).<br>
 +
In the case of requiring a larger value, you should ADD or SUB until you have the desired number, or LDR it from a data word.
 +
 +
This is encoded into the instruction as:
 +
[[Image:Shift_immediate_constant.png|center]]
 +
 +
 +
'''Register''' values are references to a register, for example:
 +
  ADD  R0, R1, R2
 +
As a technical note, this is actually stored in memory as a Logical Shift Left by immediate with the shift being zero.
 +
 +
This is encoded into the instruction as:
 +
[[Image:Shift_immediate_register.png|center]]
 +
 +
 
===The barrel shifter===
 
===The barrel shifter===
 
The ARM processor incorporates a barrel shifter that can be used with the data processing instructions ([[ADC]], [[ADD]], [[AND]], [[BIC]], [[CMN]], [[CMP]], [[EOR]], [[MOV]], [[MVN]], [[ORR]], [[RSB]], [[SBC]], [[SUB]], [[TEQ]], [[TST]]). You can also use the barrel shifter to affect the index value in [[LDR]]/[[STR]] operations.
 
The ARM processor incorporates a barrel shifter that can be used with the data processing instructions ([[ADC]], [[ADD]], [[AND]], [[BIC]], [[CMN]], [[CMP]], [[EOR]], [[MOV]], [[MVN]], [[ORR]], [[RSB]], [[SBC]], [[SUB]], [[TEQ]], [[TST]]). You can also use the barrel shifter to affect the index value in [[LDR]]/[[STR]] operations.
Line 32: Line 56:
  
 
On exit, R0 is 48. The instructions forming the sum <code>R0 = #12, LSL#2</code> is equivalent to the BASIC <code>R0 = 12 << 2</code>, or in maths form, <code>R0 = 12 &times; 4</code>.
 
On exit, R0 is 48. The instructions forming the sum <code>R0 = #12, LSL#2</code> is equivalent to the BASIC <code>R0 = 12 << 2</code>, or in maths form, <code>R0 = 12 &times; 4</code>.
 +
 +
This shift is encoded for immediate shifts as:
 +
[[Image:Shift_LSL_immediate.png|center]]
 +
and for register shifts as:
 +
[[Image:Shift_LSL_register.png|center]]
  
 
===Logical Shift Right===
 
===Logical Shift Right===
Line 41: Line 70:
 
[[Image:Diagram LSR.png|center|Diagram of LSR]]
 
[[Image:Diagram LSR.png|center|Diagram of LSR]]
 
The shift amount can be from one to thirty two, and the carry-out is the value of the last bit shifted out.
 
The shift amount can be from one to thirty two, and the carry-out is the value of the last bit shifted out.
 +
 +
This shift is encoded for immediate shifts as:
 +
[[Image:Shift_LSR_immediate.png|center]]
 +
and for register shifts as:
 +
[[Image:Shift_LSR_register.png|center]]
  
 
===Arithmetic Shift Right===
 
===Arithmetic Shift Right===
Line 49: Line 83:
 
This is similar to LSR, with the exception that the high bits are filled with the value of bit 31 of the register being shifted (R''x''), in order to preserve the sign in 2's complement maths. It is otherwise the same as <code>register = value >> shift</code>.
 
This is similar to LSR, with the exception that the high bits are filled with the value of bit 31 of the register being shifted (R''x''), in order to preserve the sign in 2's complement maths. It is otherwise the same as <code>register = value >> shift</code>.
 
[[Image:Diagram ASR.png|center|Diagram of ASR]]
 
[[Image:Diagram ASR.png|center|Diagram of ASR]]
 +
 +
This shift is encoded for immediate shifts as:
 +
[[Image:Shift_ASR_immediate.png|center]]
 +
and for register shifts as:
 +
[[Image:Shift_ASR_register.png|center]]
  
 
===Rotate Right===
 
===Rotate Right===
Line 58: Line 97:
 
[[Image:Diagram ROR.png|center|Diagram of ROR]]
 
[[Image:Diagram ROR.png|center|Diagram of ROR]]
 
If it was possible to specify the amount to be shifted as 32, the result would be that all the bits would be rotated by 32 places, right back to their original positions.
 
If it was possible to specify the amount to be shifted as 32, the result would be that all the bits would be rotated by 32 places, right back to their original positions.
 +
 +
It is not possible to ROR #0, as that encoding is used to signify RRX.
  
 
The carry-out is the value of the last bit shifted.
 
The carry-out is the value of the last bit shifted.
 +
 +
This shift is encoded for immediate shifts as:
 +
[[Image:Shift_ROR_immediate.png|center]]
 +
and for register shifts as:
 +
[[Image:Shift_ROR_register.png|center]]
  
 
===Rotate Right with Extend===
 
===Rotate Right with Extend===
Line 67: Line 113:
 
This is a <code>ROR #1</code> operation, which rotates ''one'' place to the right - the difference is that the processor's Carry flag is used to provide a 33 bit quantity to be shifted.
 
This is a <code>ROR #1</code> operation, which rotates ''one'' place to the right - the difference is that the processor's Carry flag is used to provide a 33 bit quantity to be shifted.
 
[[Image:Diagram RRX.png|center|Diagram of RRX]]
 
[[Image:Diagram RRX.png|center|Diagram of RRX]]
 +
 +
This shift is encoded for immediate shifts as:
 +
[[Image:Shift_RRX.png|center]]
 +
It is encoded into the space that would be used for ROR, #0.
 +
 +
 +
===How to Rotate Left with Extend===
 +
It is possible to mimic the behaviour of RRX in the leftwards direction using the [[ADC]] instruction:
 +
  ADCS  R0, R0, R0

Latest revision as of 07:18, 1 September 2011

There are eleven types of shift possible in Data Processing instructions where a "shift" is available. This document describes them.

The I bit, bit 25, of the instruction determines if the shift type is Immediate or Register. With this selection made, the lower twelve bits of the instruction define the shift.

Contents

[edit] Non shifts

There are two non-shift types - the immediate and a register reference.

Immediate values are values that are directly encoded into the instruction, such as:

  ADD   R0, R1, #123

There is, however, a slight complication in that not all values can be represented. The immediate works by optionally shifting an eight bit value. Thus, any value up to &FF is valid. Likewise, it is possible to shift that around, so &F000000F is valid, as is &000AD000. However &00000123 is not (for &123 cannot be described by rotating an eight bit value).
In the case of requiring a larger value, you should ADD or SUB until you have the desired number, or LDR it from a data word.

This is encoded into the instruction as:

Shift immediate constant.png


Register values are references to a register, for example:

  ADD   R0, R1, R2

As a technical note, this is actually stored in memory as a Logical Shift Left by immediate with the shift being zero.

This is encoded into the instruction as:

Shift immediate register.png


[edit] The barrel shifter

The ARM processor incorporates a barrel shifter that can be used with the data processing instructions (ADC, ADD, AND, BIC, CMN, CMP, EOR, MOV, MVN, ORR, RSB, SBC, SUB, TEQ, TST). You can also use the barrel shifter to affect the index value in LDR/STR operations.

There are six mnemonics for the different shift types:

  • LSL Logical Shift Left
  • ASL Arithmetic Shift Left
  • LSR Logical Shift Right
  • ASR Arithmetic Shift Right
  • ROR Rotate Right
  • RRX Rotate Right with Extend

ASL and LSL are the same, and may be freely interchanged.

You can specify a shift with an immediate value, or by a register which holds the value to be shifted by.

[edit] Logical or Arithmetic Shift Left

  Rx, LSL #n    or
  Rx, ASL #n    or
  Rx, LSL Rn    or
  Rx, ASL Rn

The contents of Rx will be taken and shifted to a more significant position by the amount specified by n or in the register Rn. The shift amount can be from zero to thirty one. The least significant bits introduced are zeroes.

The high bits shifted off to the left are discarded, except for the notional bit thirty three (i.e., the last bit to be shifted off) which becomes the value of the carry flag on exit from the barrel shifter.

Diagram of LSL

Consider the following:

  MOV    R1, #12
  MOV    R0, R1, LSL#2

On exit, R0 is 48. The instructions forming the sum R0 = #12, LSL#2 is equivalent to the BASIC R0 = 12 << 2, or in maths form, R0 = 12 × 4.

This shift is encoded for immediate shifts as:

Shift LSL immediate.png

and for register shifts as:

Shift LSL register.png

[edit] Logical Shift Right

  Rx, LSR #n    or
  Rx, LSR Rn

This does the notional opposite of shifting left. Everything is shifted to the right, to a less significant position. It is the same as register = value >>> shift.

Diagram of LSR

The shift amount can be from one to thirty two, and the carry-out is the value of the last bit shifted out.

This shift is encoded for immediate shifts as:

Shift LSR immediate.png

and for register shifts as:

Shift LSR register.png

[edit] Arithmetic Shift Right

  Rx, ASR #n    or
  Rx, ASR Rn

This is similar to LSR, with the exception that the high bits are filled with the value of bit 31 of the register being shifted (Rx), in order to preserve the sign in 2's complement maths. It is otherwise the same as register = value >> shift.

Diagram of ASR

This shift is encoded for immediate shifts as:

Shift ASR immediate.png

and for register shifts as:

Shift ASR register.png

[edit] Rotate Right

  Rx, ROR #n    or
  Rx, ROR Rn

Rotate Right is similar to a Logical Shift Right, except the bits which would normally be shifted off the right are replaced on the left, thus the bits 'rotate'.

Diagram of ROR

If it was possible to specify the amount to be shifted as 32, the result would be that all the bits would be rotated by 32 places, right back to their original positions.

It is not possible to ROR #0, as that encoding is used to signify RRX.

The carry-out is the value of the last bit shifted.

This shift is encoded for immediate shifts as:

Shift ROR immediate.png

and for register shifts as:

Shift ROR register.png

[edit] Rotate Right with Extend

  Rx, RRX

This is a ROR #1 operation, which rotates one place to the right - the difference is that the processor's Carry flag is used to provide a 33 bit quantity to be shifted.

Diagram of RRX

This shift is encoded for immediate shifts as:

Shift RRX.png

It is encoded into the space that would be used for ROR, #0.


[edit] How to Rotate Left with Extend

It is possible to mimic the behaviour of RRX in the leftwards direction using the ADC instruction:

  ADCS   R0, R0, R0
Personal tools
Namespaces

Variants
Actions
Navigation
Contents
Toolbox