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