blob: f74933e691eeb61c7c39577f554f95208bfed82c [file] [log] [blame]
Greg Clayton7349bd92011-05-09 20:18:18 +00001//===-- InstructionUtils.h --------------------------------------*- C++ -*-===//
Johnny Chen74889b22011-01-26 01:00:55 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Johnny Chen74889b22011-01-26 01:00:55 +00006//
7//===----------------------------------------------------------------------===//
8
9#ifndef lldb_InstructionUtils_h_
10#define lldb_InstructionUtils_h_
11
Raphael Isemann02d4ff42018-05-26 14:59:14 +000012#include <cassert>
13#include <cstdint>
14
Johnny Chen74889b22011-01-26 01:00:55 +000015// Common utilities for manipulating instruction bit fields.
16
17namespace lldb_private {
18
Johnny Chen61938f72011-02-12 01:01:40 +000019// Return the bit field(s) from the most significant bit (msbit) to the
Caroline Ticeb5c6a3e2011-03-31 03:26:23 +000020// least significant bit (lsbit) of a 64-bit unsigned value.
Kate Stoneb9c1b512016-09-06 20:57:50 +000021static 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);
Caroline Ticeb5c6a3e2011-03-31 03:26:23 +000025}
26
27// Return the bit field(s) from the most significant bit (msbit) to the
Johnny Chen722d4e42011-02-11 23:29:14 +000028// least significant bit (lsbit) of a 32-bit unsigned value.
Kate Stoneb9c1b512016-09-06 20:57:50 +000029static 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);
Johnny Chen74889b22011-01-26 01:00:55 +000033}
34
Johnny Chen61938f72011-02-12 01:01:40 +000035// Return the bit value from the 'bit' position of a 32-bit unsigned value.
Kate Stoneb9c1b512016-09-06 20:57:50 +000036static inline uint32_t Bit32(const uint32_t bits, const uint32_t bit) {
37 return (bits >> bit) & 1u;
Greg Clayton7349bd92011-05-09 20:18:18 +000038}
39
Kate Stoneb9c1b512016-09-06 20:57:50 +000040static inline uint64_t Bit64(const uint64_t bits, const uint32_t bit) {
41 return (bits >> bit) & 1ull;
Johnny Chen0cfda5b2011-02-10 19:29:03 +000042}
43
Johnny Chen61938f72011-02-12 01:01:40 +000044// 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'.
Kate Stoneb9c1b512016-09-06 20:57:50 +000046static 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;
Johnny Chenea745e82011-02-04 23:02:47 +000052}
53
Johnny Chen61938f72011-02-12 01:01:40 +000054// Set the 'bit' position of a 32-bit unsigned value to 'val'.
Kate Stoneb9c1b512016-09-06 20:57:50 +000055static inline void SetBit32(uint32_t &bits, const uint32_t bit,
56 const uint32_t val) {
57 SetBits32(bits, bit, bit, val);
Johnny Chen0cfda5b2011-02-10 19:29:03 +000058}
59
Johnny Chen61938f72011-02-12 01:01:40 +000060// Rotate a 32-bit unsigned value right by the specified amount.
Kate Stoneb9c1b512016-09-06 20:57:50 +000061static 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));
Johnny Chen722d4e42011-02-11 23:29:14 +000064}
65
Johnny Chen61938f72011-02-12 01:01:40 +000066// Rotate a 32-bit unsigned value left by the specified amount.
Kate Stoneb9c1b512016-09-06 20:57:50 +000067static 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));
Johnny Chen722d4e42011-02-11 23:29:14 +000070}
71
Johnny Chen74889b22011-01-26 01:00:55 +000072// Create a mask that starts at bit zero and includes "bit"
Kate Stoneb9c1b512016-09-06 20:57:50 +000073static inline uint64_t MaskUpToBit(const uint64_t bit) {
74 if (bit >= 63)
75 return -1ll;
76 return (1ull << (bit + 1ull)) - 1ull;
Johnny Chen74889b22011-01-26 01:00:55 +000077}
78
Johnny Chen61938f72011-02-12 01:01:40 +000079// Return an integer result equal to the number of bits of x that are ones.
Kate Stoneb9c1b512016-09-06 20:57:50 +000080static 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;
Johnny Chen74889b22011-01-26 01:00:55 +000087}
88
Kate Stoneb9c1b512016-09-06 20:57:50 +000089static inline bool BitIsSet(const uint64_t value, const uint64_t bit) {
90 return (value & (1ull << bit)) != 0;
Johnny Chen74889b22011-01-26 01:00:55 +000091}
92
Kate Stoneb9c1b512016-09-06 20:57:50 +000093static inline bool BitIsClear(const uint64_t value, const uint64_t bit) {
94 return (value & (1ull << bit)) == 0;
Johnny Chen74889b22011-01-26 01:00:55 +000095}
96
Kate Stoneb9c1b512016-09-06 20:57:50 +000097static 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;
Johnny Chen74889b22011-01-26 01:00:55 +0000102}
103
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104static 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;
Johnny Chen74889b22011-01-26 01:00:55 +0000112}
113
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114} // namespace lldb_private
Johnny Chen74889b22011-01-26 01:00:55 +0000115
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116#endif // lldb_InstructionUtils_h_