RTEMS Logo

RTEMS 4.7.2 On-Line Library


Miscellaneous Endian Swap Unsigned Integers

PREV UP NEXT Bookshelf RTEMS Porting Guide

10.3.1: Endian Swap Unsigned Integers

The port should provide routines to swap sixteen (CPU_swap_u16) and thirty-bit (CPU_swap_u32) unsigned integers. These are primarily used in two areas of RTEMS - multiprocessing support and the network endian swap routines. The CPU_swap_u32 routine must be implemented as a static routine rather than a macro because its address is taken and used indirectly. On the other hand, the CPU_swap_u16 routine may be implemented as a macro.

Some CPUs have special instructions that swap a 32-bit quantity in a single instruction (e.g. i486). It is probably best to avoid an "endian swapping control bit" in the CPU. One good reason is that interrupts would probably have to be disabled to insure that an interrupt does not try to access the same "chunk" with the wrong endian. Another good reason is that on some CPUs, the endian bit endianness for ALL fetches -- both code and data -- so the code will be fetched incorrectly.

The following is an implementation of the CPU_swap_u32 routine that will work on any CPU. It operates by breaking the unsigned thirty-two bit integer into four byte-wide quantities and reassemblying them.

static inline unsigned int CPU_swap_u32(
  unsigned int value
)
{
  unsigned32 byte1, byte2, byte3, byte4, swapped;

  byte4 = (value >> 24) & 0xff;
  byte3 = (value >> 16) & 0xff;
  byte2 = (value >> 8)  & 0xff;
  byte1 =  value        & 0xff;

  swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
  return( swapped );
}

Although the above implementation is portable, it is not particularly efficient. So if there is a better way to implement this on a particular CPU family or model, please do so. The efficiency of this routine has significant impact on the efficiency of the multiprocessing support code in the shared memory driver and in network applications using the ntohl() family of routines.

Most microprocessor families have rotate instructions which can be used to greatly improve the CPU_swap_u32 routine. The most common way to do this is to:

swap least significant two bytes with 16-bit rotate
swap upper and lower 16-bits
swap most significant two bytes with 16-bit rotate

Some CPUs have special instructions that swap a 32-bit quantity in a single instruction (e.g. i486). It is probably best to avoid an "endian swapping control bit" in the CPU. One good reason is that interrupts would probably have to be disabled to insure that an interrupt does not try to access the same "chunk" with the wrong endian. Another good reason is that on some CPUs, the endian bit endianness for ALL fetches -- both code and data -- so the code will be fetched incorrectly.

Similarly, here is a portable implementation of the CPU_swap_u16 routine. Just as with the CPU_swap_u32 routine, the porter should provide a better implementation if possible.

#define CPU_swap_u16( value ) \
  (((value&0xff) << 8) | ((value >> 8)&0xff))


PREV UP NEXT Bookshelf RTEMS Porting Guide

Copyright © 1988-2004 OAR Corporation