to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
117 lines
3.9 KiB
C++
117 lines
3.9 KiB
C++
//===-- InstructionUtils.h --------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef lldb_InstructionUtils_h_
|
|
#define lldb_InstructionUtils_h_
|
|
|
|
#include <cassert>
|
|
#include <cstdint>
|
|
|
|
// Common utilities for manipulating instruction bit fields.
|
|
|
|
namespace lldb_private {
|
|
|
|
// Return the bit field(s) from the most significant bit (msbit) to the
|
|
// least significant bit (lsbit) of a 64-bit unsigned value.
|
|
static inline uint64_t Bits64(const uint64_t bits, const uint32_t msbit,
|
|
const uint32_t lsbit) {
|
|
assert(msbit < 64 && lsbit <= msbit);
|
|
return (bits >> lsbit) & ((1ull << (msbit - lsbit + 1)) - 1);
|
|
}
|
|
|
|
// Return the bit field(s) from the most significant bit (msbit) to the
|
|
// least significant bit (lsbit) of a 32-bit unsigned value.
|
|
static inline uint32_t Bits32(const uint32_t bits, const uint32_t msbit,
|
|
const uint32_t lsbit) {
|
|
assert(msbit < 32 && lsbit <= msbit);
|
|
return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1);
|
|
}
|
|
|
|
// Return the bit value from the 'bit' position of a 32-bit unsigned value.
|
|
static inline uint32_t Bit32(const uint32_t bits, const uint32_t bit) {
|
|
return (bits >> bit) & 1u;
|
|
}
|
|
|
|
static inline uint64_t Bit64(const uint64_t bits, const uint32_t bit) {
|
|
return (bits >> bit) & 1ull;
|
|
}
|
|
|
|
// Set the bit field(s) from the most significant bit (msbit) to the
|
|
// least significant bit (lsbit) of a 32-bit unsigned value to 'val'.
|
|
static inline void SetBits32(uint32_t &bits, const uint32_t msbit,
|
|
const uint32_t lsbit, const uint32_t val) {
|
|
assert(msbit < 32 && lsbit < 32 && msbit >= lsbit);
|
|
uint32_t mask = ((1u << (msbit - lsbit + 1)) - 1);
|
|
bits &= ~(mask << lsbit);
|
|
bits |= (val & mask) << lsbit;
|
|
}
|
|
|
|
// Set the 'bit' position of a 32-bit unsigned value to 'val'.
|
|
static inline void SetBit32(uint32_t &bits, const uint32_t bit,
|
|
const uint32_t val) {
|
|
SetBits32(bits, bit, bit, val);
|
|
}
|
|
|
|
// Rotate a 32-bit unsigned value right by the specified amount.
|
|
static inline uint32_t Rotr32(uint32_t bits, uint32_t amt) {
|
|
assert(amt < 32 && "Invalid rotate amount");
|
|
return (bits >> amt) | (bits << ((32 - amt) & 31));
|
|
}
|
|
|
|
// Rotate a 32-bit unsigned value left by the specified amount.
|
|
static inline uint32_t Rotl32(uint32_t bits, uint32_t amt) {
|
|
assert(amt < 32 && "Invalid rotate amount");
|
|
return (bits << amt) | (bits >> ((32 - amt) & 31));
|
|
}
|
|
|
|
// Create a mask that starts at bit zero and includes "bit"
|
|
static inline uint64_t MaskUpToBit(const uint64_t bit) {
|
|
if (bit >= 63)
|
|
return -1ll;
|
|
return (1ull << (bit + 1ull)) - 1ull;
|
|
}
|
|
|
|
// Return an integer result equal to the number of bits of x that are ones.
|
|
static inline uint32_t BitCount(uint64_t x) {
|
|
// c accumulates the total bits set in x
|
|
uint32_t c;
|
|
for (c = 0; x; ++c) {
|
|
x &= x - 1; // clear the least significant bit set
|
|
}
|
|
return c;
|
|
}
|
|
|
|
static inline bool BitIsSet(const uint64_t value, const uint64_t bit) {
|
|
return (value & (1ull << bit)) != 0;
|
|
}
|
|
|
|
static inline bool BitIsClear(const uint64_t value, const uint64_t bit) {
|
|
return (value & (1ull << bit)) == 0;
|
|
}
|
|
|
|
static inline uint64_t UnsignedBits(const uint64_t value, const uint64_t msbit,
|
|
const uint64_t lsbit) {
|
|
uint64_t result = value >> lsbit;
|
|
result &= MaskUpToBit(msbit - lsbit);
|
|
return result;
|
|
}
|
|
|
|
static inline int64_t SignedBits(const uint64_t value, const uint64_t msbit,
|
|
const uint64_t lsbit) {
|
|
uint64_t result = UnsignedBits(value, msbit, lsbit);
|
|
if (BitIsSet(value, msbit)) {
|
|
// Sign extend
|
|
result |= ~MaskUpToBit(msbit - lsbit);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
} // namespace lldb_private
|
|
|
|
#endif // lldb_InstructionUtils_h_
|