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