| Index: gold/utils.h
|
| ===================================================================
|
| new file mode 100644
|
| --- /dev/null
|
| +++ b/gold/utils.h
|
| @@ -0,0 +1,95 @@
|
| +// utils.h -- utilities for manipulating integers of up to 32-bits.
|
| +
|
| +// Copyright 2011 Free Software Foundation, Inc.
|
| +// Written by Aleksandar Simeonov <aleksandar.simeonov@rt-rk.com>
|
| +// based on the ARM code written by Doug Kwan <dougkwan@google.com>
|
| +
|
| +// This file is part of gold.
|
| +
|
| +// This program is free software; you can redistribute it and/or modify
|
| +// it under the terms of the GNU General Public License as published by
|
| +// the Free Software Foundation; either version 3 of the License, or
|
| +// (at your option) any later version.
|
| +
|
| +// This 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 program; if not, write to the Free Software
|
| +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
| +// MA 02110-1301, USA.
|
| +
|
| +#ifndef GOLD_UTILS_H
|
| +#define GOLD_UTILS_H
|
| +
|
| +namespace gold
|
| +{
|
| +// Utilities for manipulating integers of up to 32-bits
|
| +
|
| +namespace utils
|
| +{
|
| + // Sign extend an n-bit unsigned integer stored in an uint32_t into
|
| + // an int32_t. NO_BITS must be between 1 to 32.
|
| +
|
| + template<int no_bits>
|
| + inline int32_t
|
| + sign_extend(uint32_t bits)
|
| + {
|
| + gold_assert(no_bits >= 0 && no_bits <= 32);
|
| + if (no_bits == 32)
|
| + return static_cast<int32_t>(bits);
|
| + uint32_t mask = (~((uint32_t) 0)) >> (32 - no_bits);
|
| + bits &= mask;
|
| + uint32_t top_bit = 1U << (no_bits - 1);
|
| + int32_t as_signed = static_cast<int32_t>(bits);
|
| + return (bits & top_bit) ? as_signed + (-top_bit * 2) : as_signed;
|
| + }
|
| +
|
| + // Detects overflow of an NO_BITS integer stored in a uint32_t.
|
| +
|
| + template<int no_bits>
|
| + inline bool
|
| + has_overflow(uint32_t bits)
|
| + {
|
| + gold_assert(no_bits >= 0 && no_bits <= 32);
|
| + if (no_bits == 32)
|
| + return false;
|
| + int32_t max = (1 << (no_bits - 1)) - 1;
|
| + int32_t min = -(1 << (no_bits - 1));
|
| + int32_t as_signed = static_cast<int32_t>(bits);
|
| + return as_signed > max || as_signed < min;
|
| + }
|
| +
|
| + // Detects overflow of an NO_BITS integer stored in a uint32_t when it
|
| + // fits in the given number of bits as either a signed or unsigned value.
|
| + // For example, has_signed_unsigned_overflow<8> would check
|
| + // -128 <= bits <= 255
|
| +
|
| + template<int no_bits>
|
| + inline bool
|
| + has_signed_unsigned_overflow(uint32_t bits)
|
| + {
|
| + gold_assert(no_bits >= 2 && no_bits <= 32);
|
| + if (no_bits == 32)
|
| + return false;
|
| + int32_t max = static_cast<int32_t>((1U << no_bits) - 1);
|
| + int32_t min = -(1 << (no_bits - 1));
|
| + int32_t as_signed = static_cast<int32_t>(bits);
|
| + return as_signed > max || as_signed < min;
|
| + }
|
| +
|
| + // Select bits from A and B using bits in MASK. For each n in [0..31],
|
| + // the n-th bit in the result is chosen from the n-th bits of A and B.
|
| + // A zero selects A and a one selects B.
|
| +
|
| + inline uint32_t
|
| + bit_select(uint32_t a, uint32_t b, uint32_t mask)
|
| + { return (a & ~mask) | (b & mask); }
|
| +} // End namespace utils.
|
| +
|
| +} // End namespace gold.
|
| +
|
| +#endif // !defined(GOLD_UTILS_H)
|
| +
|
|
|