Move the generic instruction bits manipulation routines into a newly created file
named InstructionUtils.h and modify some existing code to use them.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@124259 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/Utility/ARMUtils.h b/source/Plugins/Process/Utility/ARMUtils.h
index 772bd4d..c0ad1cc 100644
--- a/source/Plugins/Process/Utility/ARMUtils.h
+++ b/source/Plugins/Process/Utility/ARMUtils.h
@@ -10,6 +10,8 @@
#ifndef lldb_ARMUtils_h_
#define lldb_ARMUtils_h_
+#include "InstructionUtils.h"
+
// Common utilities for the ARM/Thumb Instruction Set Architecture.
namespace lldb_private {
@@ -52,8 +54,7 @@
static inline uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
{
- assert(msbit < 32 && lsbit <= msbit);
- return (val >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1);
+ return Bits32(val, msbit, lsbit);
}
static inline uint32_t bit(const uint32_t val, const uint32_t msbit)
@@ -131,18 +132,6 @@
// not permitted for many Thumb register specifiers.
static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
-// Returns an integer result equal to the number of bits of x that are ones.
-static inline uint32_t BitCount(uint32_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;
-}
-
} // namespace lldb_private
#endif // lldb_ARMUtils_h_
diff --git a/source/Plugins/Process/Utility/EmulateInstruction.h b/source/Plugins/Process/Utility/EmulateInstruction.h
index 59c4a34..f7d8174 100644
--- a/source/Plugins/Process/Utility/EmulateInstruction.h
+++ b/source/Plugins/Process/Utility/EmulateInstruction.h
@@ -104,45 +104,6 @@
virtual bool
EvaluateInstruction () = 0;
- // Create a mask that starts at bit zero and includes "bit"
- static uint64_t
- MaskUpToBit (const uint64_t bit)
- {
- return (1ull << (bit + 1ull)) - 1ull;
- }
-
- static bool
- BitIsSet (const uint64_t value, const uint64_t bit)
- {
- return (value & (1ull << bit)) != 0;
- }
-
- static bool
- BitIsClear (const uint64_t value, const uint64_t bit)
- {
- return (value & (1ull << bit)) == 0;
- }
-
- static 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;
- }
-
- static 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;
- }
-
uint64_t
ReadRegisterUnsigned (uint32_t reg_kind,
uint32_t reg_num,
@@ -168,19 +129,6 @@
uint64_t uval,
size_t uval_byte_size);
- static uint32_t
- BitCount (uint64_t value)
- {
- uint32_t set_bit_count = 0;
- while (value)
- {
- if (value & 1)
- ++set_bit_count;
- value >>= 1;
- }
- return set_bit_count;
- }
-
uint32_t
GetAddressByteSize () const
{
diff --git a/source/Plugins/Process/Utility/EmulateInstructionARM.cpp b/source/Plugins/Process/Utility/EmulateInstructionARM.cpp
index 1c2739c..56a8366 100644
--- a/source/Plugins/Process/Utility/EmulateInstructionARM.cpp
+++ b/source/Plugins/Process/Utility/EmulateInstructionARM.cpp
@@ -111,9 +111,9 @@
uint32_t Rt; // the source register
switch (encoding) {
case eEncodingT1:
- registers = EmulateInstruction::UnsignedBits (opcode, 7, 0);
+ registers = Bits32(opcode, 7, 0);
// The M bit represents LR.
- if (EmulateInstruction::UnsignedBits (opcode, 8, 8))
+ if (Bits32(opcode, 8, 8))
registers |= 0x000eu;
// if BitCount(registers) < 1 then UNPREDICTABLE;
if (BitCount(registers) < 1)
@@ -121,26 +121,26 @@
break;
case eEncodingT2:
// Ignore bits 15 & 13.
- registers = EmulateInstruction::UnsignedBits (opcode, 15, 0) & ~0xa000;
+ registers = Bits32(opcode, 15, 0) & ~0xa000;
// if BitCount(registers) < 2 then UNPREDICTABLE;
if (BitCount(registers) < 2)
return false;
break;
case eEncodingT3:
- Rt = EmulateInstruction::UnsignedBits (opcode, 15, 12);
+ Rt = Bits32(opcode, 15, 12);
// if BadReg(t) then UNPREDICTABLE;
if (BadReg(Rt))
return false;
registers = (1u << Rt);
break;
case eEncodingA1:
- registers = EmulateInstruction::UnsignedBits (opcode, 15, 0);
+ registers = Bits32(opcode, 15, 0);
// Instead of return false, let's handle the following case as well,
// which amounts to pushing one reg onto the full descending stacks.
// if BitCount(register_list) < 2 then SEE STMDB / STMFD;
break;
case eEncodingA2:
- Rt = EmulateInstruction::UnsignedBits (opcode, 15, 12);
+ Rt = Bits32(opcode, 15, 12);
// if t == 13 then UNPREDICTABLE;
if (Rt == dwarf_sp)
return false;
@@ -156,7 +156,7 @@
EmulateInstruction::Context context = { EmulateInstruction::eContextPushRegisterOnStack, eRegisterKindDWARF, 0, 0 };
for (i=0; i<15; ++i)
{
- if (EmulateInstruction::BitIsSet (registers, 1u << i))
+ if (BitIsSet (registers, 1u << i))
{
context.arg1 = dwarf_r0 + i; // arg1 in the context is the DWARF register number
context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset
@@ -169,7 +169,7 @@
}
}
- if (EmulateInstruction::BitIsSet (registers, 1u << 15))
+ if (BitIsSet (registers, 1u << 15))
{
context.arg1 = dwarf_pc; // arg1 in the context is the DWARF register number
context.arg2 = addr - sp; // arg2 in the context is the stack pointer offset
@@ -284,8 +284,8 @@
uint32_t imm12;
switch (encoding) {
case eEncodingA1:
- Rt = EmulateInstruction::UnsignedBits (opcode, 15, 12);
- imm12 = EmulateInstruction::UnsignedBits (opcode, 11, 0);
+ Rt = Bits32(opcode, 15, 12);
+ imm12 = Bits32(opcode, 11, 0);
break;
default:
return false;
diff --git a/source/Plugins/Process/Utility/InstructionUtils.h b/source/Plugins/Process/Utility/InstructionUtils.h
new file mode 100644
index 0000000..1dc3feb
--- /dev/null
+++ b/source/Plugins/Process/Utility/InstructionUtils.h
@@ -0,0 +1,78 @@
+//===-- lldb_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 {
+
+static inline uint32_t
+Bits32 (const uint32_t value, const uint32_t msbit, const uint32_t lsbit)
+{
+ assert(msbit < 32 && lsbit <= msbit);
+ return (value >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1);
+}
+
+// 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;
+}
+
+// Returns 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_