OLD | NEW |
(Empty) | |
| 1 // utils.h -- utilities for manipulating integers of up to 32-bits. |
| 2 |
| 3 // Copyright 2011 Free Software Foundation, Inc. |
| 4 // Written by Aleksandar Simeonov <aleksandar.simeonov@rt-rk.com> |
| 5 // based on the ARM code written by Doug Kwan <dougkwan@google.com> |
| 6 |
| 7 // This file is part of gold. |
| 8 |
| 9 // This program is free software; you can redistribute it and/or modify |
| 10 // it under the terms of the GNU General Public License as published by |
| 11 // the Free Software Foundation; either version 3 of the License, or |
| 12 // (at your option) any later version. |
| 13 |
| 14 // This program is distributed in the hope that it will be useful, |
| 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 17 // GNU General Public License for more details. |
| 18 |
| 19 // You should have received a copy of the GNU General Public License |
| 20 // along with this program; if not, write to the Free Software |
| 21 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
| 22 // MA 02110-1301, USA. |
| 23 |
| 24 #ifndef GOLD_UTILS_H |
| 25 #define GOLD_UTILS_H |
| 26 |
| 27 namespace gold |
| 28 { |
| 29 // Utilities for manipulating integers of up to 32-bits |
| 30 |
| 31 namespace utils |
| 32 { |
| 33 // Sign extend an n-bit unsigned integer stored in an uint32_t into |
| 34 // an int32_t. NO_BITS must be between 1 to 32. |
| 35 |
| 36 template<int no_bits> |
| 37 inline int32_t |
| 38 sign_extend(uint32_t bits) |
| 39 { |
| 40 gold_assert(no_bits >= 0 && no_bits <= 32); |
| 41 if (no_bits == 32) |
| 42 return static_cast<int32_t>(bits); |
| 43 uint32_t mask = (~((uint32_t) 0)) >> (32 - no_bits); |
| 44 bits &= mask; |
| 45 uint32_t top_bit = 1U << (no_bits - 1); |
| 46 int32_t as_signed = static_cast<int32_t>(bits); |
| 47 return (bits & top_bit) ? as_signed + (-top_bit * 2) : as_signed; |
| 48 } |
| 49 |
| 50 // Detects overflow of an NO_BITS integer stored in a uint32_t. |
| 51 |
| 52 template<int no_bits> |
| 53 inline bool |
| 54 has_overflow(uint32_t bits) |
| 55 { |
| 56 gold_assert(no_bits >= 0 && no_bits <= 32); |
| 57 if (no_bits == 32) |
| 58 return false; |
| 59 int32_t max = (1 << (no_bits - 1)) - 1; |
| 60 int32_t min = -(1 << (no_bits - 1)); |
| 61 int32_t as_signed = static_cast<int32_t>(bits); |
| 62 return as_signed > max || as_signed < min; |
| 63 } |
| 64 |
| 65 // Detects overflow of an NO_BITS integer stored in a uint32_t when it |
| 66 // fits in the given number of bits as either a signed or unsigned value. |
| 67 // For example, has_signed_unsigned_overflow<8> would check |
| 68 // -128 <= bits <= 255 |
| 69 |
| 70 template<int no_bits> |
| 71 inline bool |
| 72 has_signed_unsigned_overflow(uint32_t bits) |
| 73 { |
| 74 gold_assert(no_bits >= 2 && no_bits <= 32); |
| 75 if (no_bits == 32) |
| 76 return false; |
| 77 int32_t max = static_cast<int32_t>((1U << no_bits) - 1); |
| 78 int32_t min = -(1 << (no_bits - 1)); |
| 79 int32_t as_signed = static_cast<int32_t>(bits); |
| 80 return as_signed > max || as_signed < min; |
| 81 } |
| 82 |
| 83 // Select bits from A and B using bits in MASK. For each n in [0..31], |
| 84 // the n-th bit in the result is chosen from the n-th bits of A and B. |
| 85 // A zero selects A and a one selects B. |
| 86 |
| 87 inline uint32_t |
| 88 bit_select(uint32_t a, uint32_t b, uint32_t mask) |
| 89 { return (a & ~mask) | (b & mask); } |
| 90 } // End namespace utils. |
| 91 |
| 92 } // End namespace gold. |
| 93 |
| 94 #endif // !defined(GOLD_UTILS_H) |
| 95 |
OLD | NEW |