Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / bl / lib / utl / src / BL_Utils.h
/*
* ========== Copyright Header Begin ==========================================
*
* OpenSPARC T2 Processor File: BL_Utils.h
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
*
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ========== Copyright Header End ============================================
*/
#ifndef __BL_Utils_h__
#define __BL_Utils_h__
#include "BL_Types.h"
//Extract a range of bits from a 64-bit word.
inline uint64_t bit_selection(uint64_t v,uint8_t e,uint8_t s)
{
assert((e-s) <= 63);
if((e-s) == 63)
return v;
else
return ((v) & (((1ULL << ((e)-(s)+1))-1)<<(s)));
}
//Extract and downshift a bitfield indexed by (s)tarting
//offset and (len)gth from a (v)alue
inline uint64_t bit_shift(uint64_t v,uint8_t s,uint8_t len)
{
return (bit_selection(v,((s)+(len-1)),s)>>(s));
}
// get_lsb() isolated the least significat bit in v. This
// works through the carry generated by twos complement
// negate operation.
inline uint64_t get_lsb( uint64_t v )
{
return v & -v;
}
// clr_lsb() clears the least significant of v. Note this
// works through the borrow logic generated by - 1
inline uint64_t clr_lsb( uint64_t v )
{
return v & (v - 1);
}
// is_power_two() returns true when value v is a power of two.
// The routines fails for v == 0 ... you'll have to add that
// zero test explicitely.
inline bool is_power_of_two( uint64_t v )
{
return clr_lsb(v) == 0;
}
// bit2idx() returns the index of the set bit in v. It uses a
// De Bruijn sequence, which is a cyclic sequence of n bits in
// which no sequence of n bits appears more then once.
// http://en.wikipedia.org/wiki/De_Bruijn_sequence. The magic
// sequence in the constant multiplier in the function below.
// The value v has to be a power of two.
static inline uint_t bit2idx( uint32_t v )
{
assert(is_power_of_two(v));
static uint_t bit2tbl[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
// Note that we ignore bit 32 and above of the multiply result
// as the type is uint32_t.
return bit2tbl[(v * 0x077CB531) >> 27];
}
// rounds a value down to a power_of_two.
inline uint64_t round_down_to_power_of_two(uint64_t value, uint64_t power_of_two)
{
assert(is_power_of_two(power_of_two));
return value & ~(power_of_two - 1);
}
#endif