2015-06-01 15:28:29 +00:00
|
|
|
#include "trick/attributes.h"
|
|
|
|
#include "trick/bitfield_proto.h"
|
2015-02-26 15:02:31 +00:00
|
|
|
|
|
|
|
/* Who is using this? (Alex 04/16/12) */
|
|
|
|
|
|
|
|
void addr_bitfield(ATTRIBUTES *A, ATTRIBUTES *B, int field_count) {
|
|
|
|
// A is last non-bit field in struct
|
|
|
|
// B is bit field to process
|
|
|
|
static int bitfield_offset, bitfield_bits_used ;
|
|
|
|
static int misalign_bytes, prev_item_size;
|
|
|
|
int used_bytes, ii, dims;
|
|
|
|
int offset, item_size, item_bits ;
|
|
|
|
int bitfield_max, bitfield_align;
|
|
|
|
#define BITS_PER_BYTE 8
|
|
|
|
|
|
|
|
// a null bitfield means 0 length - go to next bit container
|
|
|
|
// field_count will be the container size in this case
|
|
|
|
if (B==NULL) {
|
|
|
|
bitfield_offset = bitfield_offset - (bitfield_offset % field_count) + field_count ;
|
|
|
|
bitfield_bits_used = 0 ;
|
|
|
|
prev_item_size = field_count;
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
|
|
|
// offset is where bitfield group will start in struct
|
|
|
|
if (A==NULL) {
|
|
|
|
offset = 0 ;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// compute offset from previous struct field
|
|
|
|
dims = 1;
|
|
|
|
if (A->num_index > 0) {
|
|
|
|
for (ii = 0; ii<A->num_index; ii++) dims *= A->index[ii].size;
|
|
|
|
}
|
|
|
|
offset = A->offset + (A->size * dims);
|
|
|
|
}
|
|
|
|
if (field_count==1) {
|
|
|
|
// start of bitfield group
|
|
|
|
bitfield_offset = offset ;
|
|
|
|
bitfield_bits_used = 0 ;
|
|
|
|
misalign_bytes = 0;
|
|
|
|
}
|
|
|
|
// backward compatibility: if started on even boundary, treat short same as int
|
|
|
|
// current sim users expect shorts to be addressed and returned as ints
|
|
|
|
// (i.e. any bitfield declared as short should not span a short boundary)
|
|
|
|
// GOOD: short x:8; short y:4; short z:4;
|
|
|
|
// BAD: short x:8; short y:6; short z:6;
|
|
|
|
if ((B->size==sizeof(short)) && (bitfield_offset-misalign_bytes) % 2 == 0) {
|
|
|
|
B->size = sizeof(int);
|
|
|
|
}
|
|
|
|
item_size = B->size ;
|
|
|
|
item_bits = B->index[0].size ;
|
|
|
|
bitfield_max = item_size * BITS_PER_BYTE ;
|
|
|
|
if (field_count==1) {
|
|
|
|
// when you start an int/short not on an int/short boundary, account for it as used bits
|
|
|
|
misalign_bytes = (bitfield_offset % item_size);
|
|
|
|
bitfield_bits_used = misalign_bytes * BITS_PER_BYTE;
|
|
|
|
bitfield_offset -= misalign_bytes;
|
|
|
|
prev_item_size = item_size;
|
|
|
|
}
|
|
|
|
if (item_size != prev_item_size) {
|
|
|
|
// go to next bit container if bitfield different declared size than previous
|
|
|
|
used_bytes = (bitfield_bits_used / BITS_PER_BYTE) + ((bitfield_bits_used % BITS_PER_BYTE) > 0);
|
|
|
|
bitfield_offset += used_bytes;
|
|
|
|
bitfield_align = (item_size > 1) && (bitfield_offset % 2); // on even boundary if not char
|
|
|
|
bitfield_offset += bitfield_align;
|
|
|
|
bitfield_bits_used = 0;
|
|
|
|
misalign_bytes = 0;
|
|
|
|
} else {
|
|
|
|
// same declared size
|
|
|
|
if (item_bits + bitfield_bits_used > bitfield_max) {
|
|
|
|
// go to next bit container if it won't fit here
|
|
|
|
bitfield_offset += item_size ;
|
|
|
|
bitfield_bits_used = bitfield_max < bitfield_bits_used ? bitfield_bits_used-bitfield_max : 0 ;
|
|
|
|
misalign_bytes = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
B->offset = bitfield_offset ;
|
|
|
|
B->index[0].start = bitfield_max - bitfield_bits_used - item_bits ;
|
|
|
|
bitfield_bits_used += item_bits ;
|
|
|
|
prev_item_size = item_size;
|
|
|
|
}
|
|
|
|
|