parrotcode: Byteordering functions | |
Contents | C |
src/byteorder.c - Byteordering functions
These are assigned to a vtable when the PBC file is loaded.
If the vtable method for conversion from the native byteorder is called, it is a no op and will work, but the caller should know if the byteorder in the PBC file is native and skip the conversion and just map it in.
Configure will have checked for supported word sizes.
*/
#include "parrot/parrot.h" #include "parrot/packfile.h"
/* HEADERIZER HFILE: include/parrot/packfile.h */
/*
FUNCDOC: fetch_iv_le
This function converts a 4 or 8 byte INTVAL
into little endian format.
If the native format is already little endian,
then no conversion is done.
*/
PARROT_WARN_UNUSED_RESULT PARROT_CONST_FUNCTION INTVAL fetch_iv_le(INTVAL w) { #if !PARROT_BIGENDIAN return w; #else # if INTVAL_SIZE == 4 return (w << 24) | ((w & 0xff00) << 8) | ((w & 0xff0000) >> 8) | (w >> 24); # else INTVAL r;
r = w << 56;
r |= (w & 0xff00) << 40;
r |= (w & 0xff0000) << 24;
r |= (w & 0xff000000) << 8;
r |= (w & 0xff00000000) >> 8;
r |= (w & 0xff0000000000) >> 24;
r |= (w & 0xff000000000000) >> 40;
r |= (w & 0xff00000000000000) >> 56;
return r;
# endif
#endif
}
/*
FUNCDOC: fetch_iv_be
This function converts a 4 or 8 byte INTVAL
into big endian format. If the native format is already big endian, then no conversion is done.
*/
PARROT_WARN_UNUSED_RESULT PARROT_CONST_FUNCTION INTVAL fetch_iv_be(INTVAL w) { #if PARROT_BIGENDIAN return w; #else # if INTVAL_SIZE == 4 return (w << 24) | ((w & 0xff00) << 8) | ((w & 0xff0000) >> 8) | (w >> 24); # else INTVAL r; r = w << 56; r |= (w & 0xff00) << 40; r |= (w & 0xff0000) << 24; r |= (w & 0xff000000) << 8; r |= (w & 0xff00000000) >> 8; r |= (w & 0xff0000000000) >> 24; r |= (w & 0xff000000000000) >> 40; r |= (w & 0xff00000000000000) >> 56; return r; # endif #endif }
/*
FUNCDOC: fetch_op_be
Same as fetch_iv_be
for opcode_t
*/
PARROT_WARN_UNUSED_RESULT PARROT_CONST_FUNCTION opcode_t fetch_op_be(opcode_t w) { #if PARROT_BIGENDIAN return w; #else # if OPCODE_T_SIZE == 4 return (w << 24) | ((w & 0x0000ff00) << 8) | ((w & 0x00ff0000) >> 8) | ((w & 0xff000000) >> 24); # else opcode_t r;
r = w << 56;
r |= (w & 0xff00) << 40;
r |= (w & 0xff0000) << 24;
r |= (w & 0xff000000) << 8;
r |= (w & 0xff00000000) >> 8;
r |= (w & 0xff0000000000) >> 24;
r |= (w & 0xff000000000000) >> 40;
r |= (w & 0xff00000000000000) >> 56;
return r;
# endif
#endif
}
/*
FUNCDOC: fetch_op_le
Same as fetch_iv_le
for opcode_t
*/
PARROT_WARN_UNUSED_RESULT PARROT_CONST_FUNCTION opcode_t fetch_op_le(opcode_t w) { #if !PARROT_BIGENDIAN return w; #else # if OPCODE_T_SIZE == 4 return (w << 24) | ((w & 0x0000ff00) << 8) | ((w & 0x00ff0000) >> 8) | ((w & 0xff000000) >> 24); # else opcode_t r;
r = w << 56;
r |= (w & 0xff00) << 40;
r |= (w & 0xff0000) << 24;
r |= (w & 0xff000000) << 8;
r |= (w & 0xff00000000) >> 8;
r |= (w & 0xff0000000000) >> 24;
r |= (w & 0xff000000000000) >> 40;
r |= (w & 0xff00000000000000) >> 56;
return r;
# endif
#endif
}
/*
Unrolled routines for swapping various sizes from 32-128 bits. These should only be used if alignment is unknown or we are pulling something out of a padded buffer.
*/
void fetch_buf_be_4(NOTNULL(unsigned char *rb), NOTNULL(const unsigned char *b)) { #if PARROT_BIGENDIAN memcpy(rb, b, 4); #else rb[0] = b[3]; rb[1] = b[2]; rb[2] = b[1]; rb[3] = b[0]; #endif }
void fetch_buf_le_4(NOTNULL(unsigned char *rb), NOTNULL(const unsigned char *b)) { #if !PARROT_BIGENDIAN memcpy(rb, b, 4); #else rb[0] = b[3]; rb[1] = b[2]; rb[2] = b[1]; rb[3] = b[0]; #endif }
void fetch_buf_be_8(NOTNULL(unsigned char *rb), NOTNULL(const unsigned char *b)) { #if PARROT_BIGENDIAN memcpy(rb, b, 8); #else rb[0] = b[7]; rb[1] = b[6]; rb[2] = b[5]; rb[3] = b[4]; rb[4] = b[3]; rb[5] = b[2]; rb[6] = b[1]; rb[7] = b[0]; #endif }
void fetch_buf_le_8(NOTNULL(unsigned char *rb), NOTNULL(const unsigned char *b)) { #if !PARROT_BIGENDIAN memcpy(rb, b, 8); #else rb[0] = b[7]; rb[1] = b[6]; rb[2] = b[5]; rb[3] = b[4]; rb[4] = b[3]; rb[5] = b[2]; rb[6] = b[1]; rb[7] = b[0]; #endif }
void fetch_buf_le_12(NOTNULL(unsigned char *rb), NOTNULL(const unsigned char *b)) { #if !PARROT_BIGENDIAN memcpy(rb, b, 12); #else rb[0] = b[11]; rb[1] = b[10]; rb[2] = b[9]; rb[3] = b[8]; rb[4] = b[7]; rb[5] = b[6]; rb[6] = b[5]; rb[7] = b[4]; rb[8] = b[3]; rb[9] = b[2]; rb[10] = b[1]; rb[11] = b[0]; #endif }
void fetch_buf_be_12(NOTNULL(unsigned char *rb), NOTNULL(const unsigned char *b)) { #if PARROT_BIGENDIAN memcpy(rb, b, 12); #else rb[0] = b[11]; rb[1] = b[10]; rb[2] = b[9]; rb[3] = b[8]; rb[4] = b[7]; rb[5] = b[6]; rb[6] = b[5]; rb[7] = b[4]; rb[8] = b[3]; rb[9] = b[2]; rb[10] = b[1]; rb[11] = b[0]; #endif }
void fetch_buf_le_16(NOTNULL(unsigned char *rb), NOTNULL(const unsigned char *b)) { #if !PARROT_BIGENDIAN memcpy(rb, b, 16); #else rb[0] = b[15]; rb[1] = b[14]; rb[2] = b[13]; rb[3] = b[12]; rb[4] = b[11]; rb[5] = b[10]; rb[6] = b[9]; rb[7] = b[8]; rb[8] = b[7]; rb[9] = b[6]; rb[10] = b[5]; rb[11] = b[4]; rb[12] = b[3]; rb[13] = b[2]; rb[14] = b[1]; rb[15] = b[0]; #endif }
void fetch_buf_be_16(NOTNULL(unsigned char *rb), NOTNULL(const unsigned char *b)) { #if PARROT_BIGENDIAN memcpy(rb, b, 16); #else rb[0] = b[15]; rb[1] = b[14]; rb[2] = b[13]; rb[3] = b[12]; rb[4] = b[11]; rb[5] = b[10]; rb[6] = b[9]; rb[7] = b[8]; rb[8] = b[7]; rb[9] = b[6]; rb[10] = b[5]; rb[11] = b[4]; rb[12] = b[3]; rb[13] = b[2]; rb[14] = b[1]; rb[15] = b[0]; #endif }
/*
Initial version by Melvin on 2002/05/01
*/
/* * Local variables: * c-file-style: "parrot" * End: * vim: expandtab shiftwidth=4: */
|