trick/trick_source/sim_services/MemoryManager/extract_bitfield.c
Alex Lin 19025d77ad Standardize directory names
Reorganized.  Created a new top level include directory that will hold all of Trick's header files. Moved all of the Trick headers to this directory.  Created a libexec directory that holds all of the executables that users don't need to execute directly.  Changed all of the executables remaining in bin to start with "trick-".  In the sim_services directories changed all source files to find the Trick headers in their new location.  Since all of the include files are gone in sim_services, removed the src directories as well, moving all of the source files up a level.  Moved the makefiles, docs, man, and other architecture independent files into a top level share directory.  Renamed lib_${TRICK_HOST_CPU} to lib64 or lib depending on the platform we're currently on.

refs #63
2015-06-09 08:44:42 -05:00

124 lines
3.4 KiB
C

/*
PURPOSE: (Extract a bitfield. And return bitfield value.)
REFERENCE: ((meow) (woof))
PROGRAMMERS: (((Jane Falgout) (Lincom)) ((Alex Lin) (NASA) (8/00))) */
#include "trick/bitfield_proto.h"
int extract_bitfield_any(int value, /* In: Value to extract bits from */
int size, /* In: Declared size of bitfield */
int start, /* In: Starting bit */
int bits)
{ /* In: Number of bits in bitfield */
int i = 0, j = 0;
unsigned int mask;
unsigned int bf;
int sbf;
union {
long l;
char c[sizeof(long)];
} un;
un.l = 1; /* Used for Little/Big Endian Detection */
bf = 0x00000000;
sbf = 0x00000000;
if (un.c[sizeof(long) - 1] == 1) {
/*
* Big endian
*/
mask = 0x00000001 << (start + bits - 1);
if (mask & value) {
/*
* This is a negative value
*/
for (i = start, j = 0; j < bits; i++, j++) {
/*
* First, turn off all bits associated with
* this bit field within the unsigned integer.
* Then assign the input value to the
* appropriate bits in the unsigned integer.
*/
mask = 0x00000001 << i;
if ((value & mask) != mask) {
sbf |= mask;
}
}
sbf = -((sbf >> start) + 1);
} else {
/*
* This is a positive value
*/
for (i = start, j = 0; j < bits; i++, j++) {
/*
* First, turn off all bits associated with
* this bit field within the unsigned integer.
* Then assign the input value to the appropriate
* bits in the unsigned integer.
*/
mask = 0x00000001 << i;
if ((value & mask) == mask) {
bf |= mask;
}
}
sbf = bf >> start;
}
} else {
/*
* Little endian
*/
/*
* Shift the bit field contents of the current value
* to the lsb of the underlying int.
*/
if (size == sizeof(short)) {
value = value << 16;
} else if (size == sizeof(char)) {
value = value << 24;
}
if ((start + bits) < 32) {
bf = (value) >> (32 - start - bits);
} else {
bf = value;
}
/* Now, AND the shifted bits with a mask of the appropriate size to obtain the bitfield value. */
bf &= (0xFFFFFFFF >> (32 - bits));
/* If this bitfield is a signed bitfield and the sign bit is set, take the two's complement of the value. */
mask = 0x00000001 << (bits - 1);
if (mask & bf) {
/* This bitfield is signed and has the sign bit set. Set sbf to the reverse bits of the bitfield contents.
Then right shift and add 1. */
sbf = 0x00000000;
for (i = 0; i < bits; i++) {
mask = 0x00000001 << i;
if ((bf & mask) != mask) {
sbf |= mask;
}
}
sbf = -(sbf + 1);
} else {
sbf = bf;
}
}
return (sbf);
}