#ifndef Morpheo_BitManipulation_h #define Morpheo_BitManipulation_h /* * $Id: BitManipulation.h 88 2008-12-10 18:31:39Z rosiere $ * * [ Description ] * */ #include #include namespace morpheo { //............................................................................ // gen_mask .................................................................. //............................................................................ template T gen_mask (uint32_t size) { T mask = 0; for (uint32_t i=0; i T gen_mask (uint32_t index_max, uint32_t index_min) { return (gen_mask(index_max-index_min+1)< T gen_mask_not (uint32_t index_max, uint32_t index_min) { return ~(gen_mask(index_max-index_min+1)< T mask (T data, uint32_t index_max, uint32_t index_min) { return gen_mask (index_max,index_min) & data; } template T mask_not (T data, uint32_t index_max, uint32_t index_min) { return gen_mask_not(index_max,index_min) & data; } //............................................................................ // shift_left_logic, shift_right_logic ....................................... //............................................................................ template T shift_logic_left (uint32_t size, T data, T value) { T mask = gen_mask (size); return (mask & ((mask & data) << value)); } template T shift_logic_right (uint32_t size, T data, T value) { T mask = gen_mask (size); return (mask & ((mask & data) >> value)); } //............................................................................ // shift_logic ............................................................... //............................................................................ template T shift_logic (uint32_t size, T data, T value, bool is_direction_left) { if (is_direction_left == true) return shift_logic_left (size, data, value); else return shift_logic_right (size, data, value); } //............................................................................ // shift_left_arithmetic, shift_right_arithmetic ............................. //............................................................................ template T shift_arithmetic_left (uint32_t size, T data, T value) { bool carry = (data&1) != 0; if (carry == false) return shift_logic_left (size,data,value); else { if (value > size) return gen_mask (size); T mask = gen_mask (value); return shift_logic_left (size,data,value) | mask; } } template T shift_arithmetic_right (uint32_t size, T data, T value) { bool carry = (data&(1<<(size-1))) != 0; if (carry == false) return shift_logic_right (size,data,value); else { if (value > size) return gen_mask (size); T mask = gen_mask (value) << (size-value); return ((shift_logic_right (size,data,value)) | mask); } } //............................................................................ // shift_arithmetic .......................................................... //............................................................................ template T shift_arithmetic (uint32_t size, T data, T value, bool is_direction_left) { if (is_direction_left == true) return shift_arithmetic_left (size, data, value); else return shift_arithmetic_right (size, data, value); } //............................................................................ // shift ..................................................................... //............................................................................ template T shift (uint32_t size, T data, T value, bool is_direction_left, bool is_shift_arithmetic) { if (is_shift_arithmetic == true) return shift_arithmetic (size, data, value, is_direction_left); else return shift_logic (size, data, value, is_direction_left); } //............................................................................ // rotate_left, rotate_right ................................................. //............................................................................ template T rotate_left (uint32_t size, T data, T value) { T mask = gen_mask (size); T rotate_mask = gen_mask (value); T rotate = rotate_mask & shift_logic_right(size,data,size-value); return (mask & (shift_logic_left (size, data, value) | rotate)); } template T rotate_right (uint32_t size, T data, T value) { T mask = gen_mask (size); T rotate_mask = gen_mask (value); T rotate = shift_logic_left (size,rotate_mask & data,size-value); return (mask & (shift_logic_right (size, data, value) | rotate)); } //............................................................................ // rotate .................................................................... //............................................................................ template T rotate (uint32_t size, T data, T value, bool is_direction_left) { if (is_direction_left == true) return rotate_left (size, data, value); else return rotate_right (size, data, value); } //............................................................................ // range ..................................................................... //............................................................................ template T range (T data, uint32_t index_max, uint32_t index_min) { return (mask(data,index_max,index_min) >> index_min); } template T range (T data, uint32_t nb_bits) { return gen_mask(nb_bits) & data; } //............................................................................ // insert .................................................................... //............................................................................ template T insert (T data_old, T data_new, uint32_t index_max, uint32_t index_min) { return (mask(data_new,index_max,index_min) | mask_not(data_old,index_max,index_min)); } //............................................................................ // extend .................................................................... //............................................................................ template T extend (uint32_t size, T data, bool extend_with_sign, uint32_t nb_bits_keep) { if (size < nb_bits_keep) return data; if (extend_with_sign and ((data>>(nb_bits_keep-1))&1)) return data | (mask(gen_mask(size),size-1, nb_bits_keep)); else return data & (mask(gen_mask(size),nb_bits_keep-1, 0)); } //............................................................................ // duplicate.................................................................. //............................................................................ template T duplicate (uint32_t size, T data_src, uint32_t nb_bits, uint32_t index_min) { T data_duplicate = mask((data_src)>>index_min, nb_bits-1, 0); T data_dest = 0; for (uint32_t i=0; i < size; i+=nb_bits) data_dest |= (data_duplicate< T duplicate (uint32_t size, T data_src, uint32_t nb_bits) { return duplicate (size,data_src,nb_bits,0); } }; // end namespace morpheo #endif