1 //===-- InstructionUtils.h --------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H 10 #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H 11 12 #include <cassert> 13 #include <cstdint> 14 15 // Common utilities for manipulating instruction bit fields. 16 17 namespace lldb_private { 18 19 // Return the bit field(s) from the most significant bit (msbit) to the 20 // least significant bit (lsbit) of a 64-bit unsigned value. 21 static inline uint64_t Bits64(const uint64_t bits, const uint32_t msbit, 22 const uint32_t lsbit) { 23 assert(msbit < 64 && lsbit <= msbit); 24 return (bits >> lsbit) & ((1ull << (msbit - lsbit + 1)) - 1); 25 } 26 27 // Return the bit field(s) from the most significant bit (msbit) to the 28 // least significant bit (lsbit) of a 32-bit unsigned value. 29 static inline uint32_t Bits32(const uint32_t bits, const uint32_t msbit, 30 const uint32_t lsbit) { 31 assert(msbit < 32 && lsbit <= msbit); 32 return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1); 33 } 34 35 // Return the bit value from the 'bit' position of a 32-bit unsigned value. 36 static inline uint32_t Bit32(const uint32_t bits, const uint32_t bit) { 37 return (bits >> bit) & 1u; 38 } 39 40 static inline uint64_t Bit64(const uint64_t bits, const uint32_t bit) { 41 return (bits >> bit) & 1ull; 42 } 43 44 // Set the bit field(s) from the most significant bit (msbit) to the 45 // least significant bit (lsbit) of a 32-bit unsigned value to 'val'. 46 static inline void SetBits32(uint32_t &bits, const uint32_t msbit, 47 const uint32_t lsbit, const uint32_t val) { 48 assert(msbit < 32 && lsbit < 32 && msbit >= lsbit); 49 uint32_t mask = ((1u << (msbit - lsbit + 1)) - 1); 50 bits &= ~(mask << lsbit); 51 bits |= (val & mask) << lsbit; 52 } 53 54 // Set the 'bit' position of a 32-bit unsigned value to 'val'. 55 static inline void SetBit32(uint32_t &bits, const uint32_t bit, 56 const uint32_t val) { 57 SetBits32(bits, bit, bit, val); 58 } 59 60 // Rotate a 32-bit unsigned value right by the specified amount. 61 static inline uint32_t Rotr32(uint32_t bits, uint32_t amt) { 62 assert(amt < 32 && "Invalid rotate amount"); 63 return (bits >> amt) | (bits << ((32 - amt) & 31)); 64 } 65 66 // Rotate a 32-bit unsigned value left by the specified amount. 67 static inline uint32_t Rotl32(uint32_t bits, uint32_t amt) { 68 assert(amt < 32 && "Invalid rotate amount"); 69 return (bits << amt) | (bits >> ((32 - amt) & 31)); 70 } 71 72 // Create a mask that starts at bit zero and includes "bit" 73 static inline uint64_t MaskUpToBit(const uint64_t bit) { 74 if (bit >= 63) 75 return -1ll; 76 return (1ull << (bit + 1ull)) - 1ull; 77 } 78 79 // Return an integer result equal to the number of bits of x that are ones. 80 static inline uint32_t BitCount(uint64_t x) { 81 // c accumulates the total bits set in x 82 uint32_t c; 83 for (c = 0; x; ++c) { 84 x &= x - 1; // clear the least significant bit set 85 } 86 return c; 87 } 88 89 static inline bool BitIsSet(const uint64_t value, const uint64_t bit) { 90 return (value & (1ull << bit)) != 0; 91 } 92 93 static inline bool BitIsClear(const uint64_t value, const uint64_t bit) { 94 return (value & (1ull << bit)) == 0; 95 } 96 97 static inline uint64_t UnsignedBits(const uint64_t value, const uint64_t msbit, 98 const uint64_t lsbit) { 99 uint64_t result = value >> lsbit; 100 result &= MaskUpToBit(msbit - lsbit); 101 return result; 102 } 103 104 static inline int64_t SignedBits(const uint64_t value, const uint64_t msbit, 105 const uint64_t lsbit) { 106 uint64_t result = UnsignedBits(value, msbit, lsbit); 107 if (BitIsSet(value, msbit)) { 108 // Sign extend 109 result |= ~MaskUpToBit(msbit - lsbit); 110 } 111 return result; 112 } 113 114 } // namespace lldb_private 115 116 #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_INSTRUCTIONUTILS_H 117