5.5.5 Shift Operators

Shift operations (<< and >>, and <<= and >>= operators) for both signed and unsigned integer types are part of the C standard but are encoded by the compiler in different ways, depending on several conditions.

For the cases where the right-hand operand to the shift operator is a constant literal, and the left-hand operand is an lvalue that is not encumbered by any side-effects (for example, it is not a volatile identifier or a pointer value returned by a function call), the compiler will consider generating one of the following shift strategies.
Shift Loop
The compiler will implement the shift operation as a series of single-bit shifts executed within a loop. The loop will iterate for the required number of bits. The carry bit will be set or cleared, and this bit shifted into the vacant bit location on each iteration.
Shift by Bits
The shift operation will be performed using a combination of 8-, 4- and 1-bit shifts to make up the required shift amount, so for example a shift of 5 bits might be implemented as a shift by 4 then an additional single-bit shift. Eight-bit shifts are performed by instructions that move bytes within the value and 4-bit shifts are performed using nibble swap instructions. Single-bit shifts are performed using the available shift or rotate instructions.
Reverse Rotate
The shift is performed as a rotate operation in the reverse direction. This strategy is typically selected for shift amounts that are 1 or 2 bits shy of a shift amount that is a multiple-of-eight bits, such shift amounts of 6, 7, 14, and 15 etc. When implementing this selection, a right shift of 7 bits becomes a left rotate of 1 bit. The result may also require that bytes within the operand be moved and some bits masked to yield the correct value.

The compiler chooses the most optimum of the above shift strategies, based on the shift amount, and the type of the operand being shifted, and which of speed- or space-optimizations are in effect. A preference for speed- or space-orientated shifts, however, can be indicated on a statement-by-statement basis in the project source code with the use of the shift pragma. See The #pragma Shift Directive for more information on this directive.