1061da546Spatrick //===-- InstructionUtils.h --------------------------------------*- C++ -*-===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9*dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H
10*dda28197Spatrick #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H
11061da546Spatrick
12061da546Spatrick #include <cassert>
13061da546Spatrick #include <cstdint>
14061da546Spatrick
15061da546Spatrick // Common utilities for manipulating instruction bit fields.
16061da546Spatrick
17061da546Spatrick namespace lldb_private {
18061da546Spatrick
19061da546Spatrick // Return the bit field(s) from the most significant bit (msbit) to the
20061da546Spatrick // least significant bit (lsbit) of a 64-bit unsigned value.
Bits64(const uint64_t bits,const uint32_t msbit,const uint32_t lsbit)21061da546Spatrick static inline uint64_t Bits64(const uint64_t bits, const uint32_t msbit,
22061da546Spatrick const uint32_t lsbit) {
23061da546Spatrick assert(msbit < 64 && lsbit <= msbit);
24061da546Spatrick return (bits >> lsbit) & ((1ull << (msbit - lsbit + 1)) - 1);
25061da546Spatrick }
26061da546Spatrick
27061da546Spatrick // Return the bit field(s) from the most significant bit (msbit) to the
28061da546Spatrick // least significant bit (lsbit) of a 32-bit unsigned value.
Bits32(const uint32_t bits,const uint32_t msbit,const uint32_t lsbit)29061da546Spatrick static inline uint32_t Bits32(const uint32_t bits, const uint32_t msbit,
30061da546Spatrick const uint32_t lsbit) {
31061da546Spatrick assert(msbit < 32 && lsbit <= msbit);
32061da546Spatrick return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1);
33061da546Spatrick }
34061da546Spatrick
35061da546Spatrick // Return the bit value from the 'bit' position of a 32-bit unsigned value.
Bit32(const uint32_t bits,const uint32_t bit)36061da546Spatrick static inline uint32_t Bit32(const uint32_t bits, const uint32_t bit) {
37061da546Spatrick return (bits >> bit) & 1u;
38061da546Spatrick }
39061da546Spatrick
Bit64(const uint64_t bits,const uint32_t bit)40061da546Spatrick static inline uint64_t Bit64(const uint64_t bits, const uint32_t bit) {
41061da546Spatrick return (bits >> bit) & 1ull;
42061da546Spatrick }
43061da546Spatrick
44061da546Spatrick // Set the bit field(s) from the most significant bit (msbit) to the
45061da546Spatrick // least significant bit (lsbit) of a 32-bit unsigned value to 'val'.
SetBits32(uint32_t & bits,const uint32_t msbit,const uint32_t lsbit,const uint32_t val)46061da546Spatrick static inline void SetBits32(uint32_t &bits, const uint32_t msbit,
47061da546Spatrick const uint32_t lsbit, const uint32_t val) {
48061da546Spatrick assert(msbit < 32 && lsbit < 32 && msbit >= lsbit);
49061da546Spatrick uint32_t mask = ((1u << (msbit - lsbit + 1)) - 1);
50061da546Spatrick bits &= ~(mask << lsbit);
51061da546Spatrick bits |= (val & mask) << lsbit;
52061da546Spatrick }
53061da546Spatrick
54061da546Spatrick // Set the 'bit' position of a 32-bit unsigned value to 'val'.
SetBit32(uint32_t & bits,const uint32_t bit,const uint32_t val)55061da546Spatrick static inline void SetBit32(uint32_t &bits, const uint32_t bit,
56061da546Spatrick const uint32_t val) {
57061da546Spatrick SetBits32(bits, bit, bit, val);
58061da546Spatrick }
59061da546Spatrick
60061da546Spatrick // Rotate a 32-bit unsigned value right by the specified amount.
Rotr32(uint32_t bits,uint32_t amt)61061da546Spatrick static inline uint32_t Rotr32(uint32_t bits, uint32_t amt) {
62061da546Spatrick assert(amt < 32 && "Invalid rotate amount");
63061da546Spatrick return (bits >> amt) | (bits << ((32 - amt) & 31));
64061da546Spatrick }
65061da546Spatrick
66061da546Spatrick // Rotate a 32-bit unsigned value left by the specified amount.
Rotl32(uint32_t bits,uint32_t amt)67061da546Spatrick static inline uint32_t Rotl32(uint32_t bits, uint32_t amt) {
68061da546Spatrick assert(amt < 32 && "Invalid rotate amount");
69061da546Spatrick return (bits << amt) | (bits >> ((32 - amt) & 31));
70061da546Spatrick }
71061da546Spatrick
72061da546Spatrick // Create a mask that starts at bit zero and includes "bit"
MaskUpToBit(const uint64_t bit)73061da546Spatrick static inline uint64_t MaskUpToBit(const uint64_t bit) {
74061da546Spatrick if (bit >= 63)
75061da546Spatrick return -1ll;
76061da546Spatrick return (1ull << (bit + 1ull)) - 1ull;
77061da546Spatrick }
78061da546Spatrick
79061da546Spatrick // Return an integer result equal to the number of bits of x that are ones.
BitCount(uint64_t x)80061da546Spatrick static inline uint32_t BitCount(uint64_t x) {
81061da546Spatrick // c accumulates the total bits set in x
82061da546Spatrick uint32_t c;
83061da546Spatrick for (c = 0; x; ++c) {
84061da546Spatrick x &= x - 1; // clear the least significant bit set
85061da546Spatrick }
86061da546Spatrick return c;
87061da546Spatrick }
88061da546Spatrick
BitIsSet(const uint64_t value,const uint64_t bit)89061da546Spatrick static inline bool BitIsSet(const uint64_t value, const uint64_t bit) {
90061da546Spatrick return (value & (1ull << bit)) != 0;
91061da546Spatrick }
92061da546Spatrick
BitIsClear(const uint64_t value,const uint64_t bit)93061da546Spatrick static inline bool BitIsClear(const uint64_t value, const uint64_t bit) {
94061da546Spatrick return (value & (1ull << bit)) == 0;
95061da546Spatrick }
96061da546Spatrick
UnsignedBits(const uint64_t value,const uint64_t msbit,const uint64_t lsbit)97061da546Spatrick static inline uint64_t UnsignedBits(const uint64_t value, const uint64_t msbit,
98061da546Spatrick const uint64_t lsbit) {
99061da546Spatrick uint64_t result = value >> lsbit;
100061da546Spatrick result &= MaskUpToBit(msbit - lsbit);
101061da546Spatrick return result;
102061da546Spatrick }
103061da546Spatrick
SignedBits(const uint64_t value,const uint64_t msbit,const uint64_t lsbit)104061da546Spatrick static inline int64_t SignedBits(const uint64_t value, const uint64_t msbit,
105061da546Spatrick const uint64_t lsbit) {
106061da546Spatrick uint64_t result = UnsignedBits(value, msbit, lsbit);
107061da546Spatrick if (BitIsSet(value, msbit)) {
108061da546Spatrick // Sign extend
109061da546Spatrick result |= ~MaskUpToBit(msbit - lsbit);
110061da546Spatrick }
111061da546Spatrick return result;
112061da546Spatrick }
113061da546Spatrick
114061da546Spatrick } // namespace lldb_private
115061da546Spatrick
116*dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H
117