1254721Semaste//===-- InstructionUtils.h --------------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#ifndef lldb_InstructionUtils_h_ 10254721Semaste#define lldb_InstructionUtils_h_ 11254721Semaste 12341825Sdim#include <cassert> 13341825Sdim#include <cstdint> 14341825Sdim 15254721Semaste// Common utilities for manipulating instruction bit fields. 16254721Semaste 17254721Semastenamespace lldb_private { 18254721Semaste 19254721Semaste// Return the bit field(s) from the most significant bit (msbit) to the 20254721Semaste// least significant bit (lsbit) of a 64-bit unsigned value. 21314564Sdimstatic inline uint64_t Bits64(const uint64_t bits, const uint32_t msbit, 22314564Sdim const uint32_t lsbit) { 23314564Sdim assert(msbit < 64 && lsbit <= msbit); 24314564Sdim return (bits >> lsbit) & ((1ull << (msbit - lsbit + 1)) - 1); 25254721Semaste} 26254721Semaste 27254721Semaste// Return the bit field(s) from the most significant bit (msbit) to the 28254721Semaste// least significant bit (lsbit) of a 32-bit unsigned value. 29314564Sdimstatic inline uint32_t Bits32(const uint32_t bits, const uint32_t msbit, 30314564Sdim const uint32_t lsbit) { 31314564Sdim assert(msbit < 32 && lsbit <= msbit); 32314564Sdim return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1); 33254721Semaste} 34254721Semaste 35254721Semaste// Return the bit value from the 'bit' position of a 32-bit unsigned value. 36314564Sdimstatic inline uint32_t Bit32(const uint32_t bits, const uint32_t bit) { 37314564Sdim return (bits >> bit) & 1u; 38254721Semaste} 39254721Semaste 40314564Sdimstatic inline uint64_t Bit64(const uint64_t bits, const uint32_t bit) { 41314564Sdim return (bits >> bit) & 1ull; 42254721Semaste} 43254721Semaste 44254721Semaste// Set the bit field(s) from the most significant bit (msbit) to the 45254721Semaste// least significant bit (lsbit) of a 32-bit unsigned value to 'val'. 46314564Sdimstatic inline void SetBits32(uint32_t &bits, const uint32_t msbit, 47314564Sdim const uint32_t lsbit, const uint32_t val) { 48314564Sdim assert(msbit < 32 && lsbit < 32 && msbit >= lsbit); 49314564Sdim uint32_t mask = ((1u << (msbit - lsbit + 1)) - 1); 50314564Sdim bits &= ~(mask << lsbit); 51314564Sdim bits |= (val & mask) << lsbit; 52254721Semaste} 53254721Semaste 54254721Semaste// Set the 'bit' position of a 32-bit unsigned value to 'val'. 55314564Sdimstatic inline void SetBit32(uint32_t &bits, const uint32_t bit, 56314564Sdim const uint32_t val) { 57314564Sdim SetBits32(bits, bit, bit, val); 58254721Semaste} 59254721Semaste 60254721Semaste// Rotate a 32-bit unsigned value right by the specified amount. 61314564Sdimstatic inline uint32_t Rotr32(uint32_t bits, uint32_t amt) { 62314564Sdim assert(amt < 32 && "Invalid rotate amount"); 63314564Sdim return (bits >> amt) | (bits << ((32 - amt) & 31)); 64254721Semaste} 65254721Semaste 66254721Semaste// Rotate a 32-bit unsigned value left by the specified amount. 67314564Sdimstatic inline uint32_t Rotl32(uint32_t bits, uint32_t amt) { 68314564Sdim assert(amt < 32 && "Invalid rotate amount"); 69314564Sdim return (bits << amt) | (bits >> ((32 - amt) & 31)); 70254721Semaste} 71254721Semaste 72254721Semaste// Create a mask that starts at bit zero and includes "bit" 73314564Sdimstatic inline uint64_t MaskUpToBit(const uint64_t bit) { 74314564Sdim if (bit >= 63) 75314564Sdim return -1ll; 76314564Sdim return (1ull << (bit + 1ull)) - 1ull; 77254721Semaste} 78254721Semaste 79254721Semaste// Return an integer result equal to the number of bits of x that are ones. 80314564Sdimstatic inline uint32_t BitCount(uint64_t x) { 81314564Sdim // c accumulates the total bits set in x 82314564Sdim uint32_t c; 83314564Sdim for (c = 0; x; ++c) { 84314564Sdim x &= x - 1; // clear the least significant bit set 85314564Sdim } 86314564Sdim return c; 87254721Semaste} 88254721Semaste 89314564Sdimstatic inline bool BitIsSet(const uint64_t value, const uint64_t bit) { 90314564Sdim return (value & (1ull << bit)) != 0; 91254721Semaste} 92254721Semaste 93314564Sdimstatic inline bool BitIsClear(const uint64_t value, const uint64_t bit) { 94314564Sdim return (value & (1ull << bit)) == 0; 95254721Semaste} 96254721Semaste 97314564Sdimstatic inline uint64_t UnsignedBits(const uint64_t value, const uint64_t msbit, 98314564Sdim const uint64_t lsbit) { 99314564Sdim uint64_t result = value >> lsbit; 100314564Sdim result &= MaskUpToBit(msbit - lsbit); 101314564Sdim return result; 102254721Semaste} 103254721Semaste 104314564Sdimstatic inline int64_t SignedBits(const uint64_t value, const uint64_t msbit, 105314564Sdim const uint64_t lsbit) { 106314564Sdim uint64_t result = UnsignedBits(value, msbit, lsbit); 107314564Sdim if (BitIsSet(value, msbit)) { 108314564Sdim // Sign extend 109314564Sdim result |= ~MaskUpToBit(msbit - lsbit); 110314564Sdim } 111314564Sdim return result; 112254721Semaste} 113254721Semaste 114314564Sdim} // namespace lldb_private 115254721Semaste 116314564Sdim#endif // lldb_InstructionUtils_h_ 117