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) |
+ |