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))
Copyright © 1988-2004 OAR Corporation