Skip to content

[lldb] Add a single bit constructor for RegisterFlags::Field #69315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 23, 2023

Conversation

DavidSpickett
Copy link
Collaborator

This means you don't have to do RegisterField("", 0, 0), you can do RegisterField("", 0).

Which is useful for testing and even more useful when we are writing definitions of real registers which have 10s of single bit fields.

This means you don't have to do RegisterField("", 0, 0),
you can do RegisterField("", 0).

Which is useful for testing and even more useful when we
are writing definitions of real registers which have 10s
of single bit fields.
@llvmbot
Copy link
Member

llvmbot commented Oct 17, 2023

@llvm/pr-subscribers-lldb

Author: David Spickett (DavidSpickett)

Changes

This means you don't have to do RegisterField("", 0, 0), you can do RegisterField("", 0).

Which is useful for testing and even more useful when we are writing definitions of real registers which have 10s of single bit fields.


Full diff: https://github.com/llvm/llvm-project/pull/69315.diff

2 Files Affected:

  • (modified) lldb/include/lldb/Target/RegisterFlags.h (+6)
  • (modified) lldb/unittests/Target/RegisterFlagsTest.cpp (+19-16)
diff --git a/lldb/include/lldb/Target/RegisterFlags.h b/lldb/include/lldb/Target/RegisterFlags.h
index 8137fd27e99c2a2..ce3daa237194036 100644
--- a/lldb/include/lldb/Target/RegisterFlags.h
+++ b/lldb/include/lldb/Target/RegisterFlags.h
@@ -17,11 +17,17 @@ class RegisterFlags {
 public:
   class Field {
   public:
+    /// Where start is the least significant bit and end is the most
+    /// significant bit. The start bit must be <= the end bit.
     Field(std::string name, unsigned start, unsigned end)
         : m_name(std::move(name)), m_start(start), m_end(end) {
       assert(m_start <= m_end && "Start bit must be <= end bit.");
     }
 
+    /// Construct a single bit field.
+    Field(std::string name, unsigned bit)
+        : m_name(std::move(name)), m_start(bit), m_end(bit) {}
+
     /// Get size of the field in bits. Will always be at least 1.
     unsigned GetSizeInBits() const { return m_end - m_start + 1; }
 
diff --git a/lldb/unittests/Target/RegisterFlagsTest.cpp b/lldb/unittests/Target/RegisterFlagsTest.cpp
index 194e05959c16599..167e28d0cecb3bd 100644
--- a/lldb/unittests/Target/RegisterFlagsTest.cpp
+++ b/lldb/unittests/Target/RegisterFlagsTest.cpp
@@ -16,7 +16,7 @@ using namespace lldb;
 TEST(RegisterFlagsTest, Field) {
   // We assume that start <= end is always true, so that is not tested here.
 
-  RegisterFlags::Field f1("abc", 0, 0);
+  RegisterFlags::Field f1("abc", 0);
   ASSERT_EQ(f1.GetName(), "abc");
   // start == end means a 1 bit field.
   ASSERT_EQ(f1.GetSizeInBits(), (unsigned)1);
@@ -51,11 +51,15 @@ static RegisterFlags::Field make_field(unsigned start, unsigned end) {
   return RegisterFlags::Field("", start, end);
 }
 
+static RegisterFlags::Field make_field(unsigned bit) {
+  return RegisterFlags::Field("", bit);
+}
+
 TEST(RegisterFlagsTest, FieldOverlaps) {
   // Single bit fields
-  ASSERT_FALSE(make_field(0, 0).Overlaps(make_field(1, 1)));
-  ASSERT_TRUE(make_field(1, 1).Overlaps(make_field(1, 1)));
-  ASSERT_FALSE(make_field(1, 1).Overlaps(make_field(3, 3)));
+  ASSERT_FALSE(make_field(0, 0).Overlaps(make_field(1)));
+  ASSERT_TRUE(make_field(1, 1).Overlaps(make_field(1)));
+  ASSERT_FALSE(make_field(1, 1).Overlaps(make_field(3)));
 
   ASSERT_TRUE(make_field(0, 1).Overlaps(make_field(1, 2)));
   ASSERT_TRUE(make_field(1, 2).Overlaps(make_field(0, 1)));
@@ -71,13 +75,13 @@ TEST(RegisterFlagsTest, PaddingDistance) {
   // (start bit is higher) field first and that they do not overlap.
 
   // [field 1][field 2]
-  ASSERT_EQ(make_field(1, 1).PaddingDistance(make_field(0, 0)), 0ULL);
+  ASSERT_EQ(make_field(1, 1).PaddingDistance(make_field(0)), 0ULL);
   // [field 1][..][field 2]
-  ASSERT_EQ(make_field(2, 2).PaddingDistance(make_field(0, 0)), 1ULL);
+  ASSERT_EQ(make_field(2, 2).PaddingDistance(make_field(0)), 1ULL);
   // [field 1][field 1][field 2]
-  ASSERT_EQ(make_field(1, 2).PaddingDistance(make_field(0, 0)), 0ULL);
+  ASSERT_EQ(make_field(1, 2).PaddingDistance(make_field(0)), 0ULL);
   // [field 1][30 bits free][field 2]
-  ASSERT_EQ(make_field(31, 31).PaddingDistance(make_field(0, 0)), 30ULL);
+  ASSERT_EQ(make_field(31, 31).PaddingDistance(make_field(0)), 30ULL);
 }
 
 static void test_padding(const std::vector<RegisterFlags::Field> &fields,
@@ -99,18 +103,18 @@ TEST(RegisterFlagsTest, RegisterFlagsPadding) {
 
   // Needs padding in between the fields, single bit.
   test_padding({make_field(17, 31), make_field(0, 15)},
-               {make_field(17, 31), make_field(16, 16), make_field(0, 15)});
+               {make_field(17, 31), make_field(16), make_field(0, 15)});
   // Multiple bits of padding.
   test_padding({make_field(17, 31), make_field(0, 14)},
                {make_field(17, 31), make_field(15, 16), make_field(0, 14)});
 
   // Padding before first field, single bit.
-  test_padding({make_field(0, 30)}, {make_field(31, 31), make_field(0, 30)});
+  test_padding({make_field(0, 30)}, {make_field(31), make_field(0, 30)});
   // Multiple bits.
   test_padding({make_field(0, 15)}, {make_field(16, 31), make_field(0, 15)});
 
   // Padding after last field, single bit.
-  test_padding({make_field(1, 31)}, {make_field(1, 31), make_field(0, 0)});
+  test_padding({make_field(1, 31)}, {make_field(1, 31), make_field(0)});
   // Multiple bits.
   test_padding({make_field(2, 31)}, {make_field(2, 31), make_field(0, 1)});
 
@@ -132,9 +136,8 @@ TEST(RegisterFieldsTest, ReverseFieldOrder) {
   ASSERT_EQ(0x56781234ULL, (unsigned long long)rf2.ReverseFieldOrder(0x12345678));
 
   // Many small fields.
-  RegisterFlags rf3("", 4,
-                    {make_field(31, 31), make_field(30, 30), make_field(29, 29),
-                     make_field(28, 28)});
+  RegisterFlags rf3(
+      "", 4, {make_field(31), make_field(30), make_field(29), make_field(28)});
   ASSERT_EQ(0x00000005ULL, rf3.ReverseFieldOrder(0xA0000000));
 }
 
@@ -167,7 +170,7 @@ TEST(RegisterFlagsTest, AsTable) {
             pos_wider.AsTable(100));
 
   // Single bit fields don't need to show start and end, just one of them.
-  RegisterFlags single_bit("", 4, {make_field(31, 31)});
+  RegisterFlags single_bit("", 4, {make_field(31)});
   ASSERT_EQ("| 31 | 30-0 |\n"
             "|----|------|\n"
             "|    |      |",
@@ -177,7 +180,7 @@ TEST(RegisterFlagsTest, AsTable) {
   RegisterFlags many_fields("", 4,
                             {RegisterFlags::Field("cat", 28, 31),
                              RegisterFlags::Field("pigeon", 20, 23),
-                             RegisterFlags::Field("wolf", 12, 12),
+                             RegisterFlags::Field("wolf", 12),
                              RegisterFlags::Field("x", 0, 4)});
   ASSERT_EQ("| 31-28 | 27-24 | 23-20  | 19-13 |  12  | 11-5 | 4-0 |\n"
             "|-------|-------|--------|-------|------|------|-----|\n"

@DavidSpickett DavidSpickett changed the title [lldb] Add a single bit constructor for RegisterField [lldb] Add a single bit constructor for RegisterFlags::Field Oct 17, 2023
Copy link
Member

@bulbazord bulbazord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me since this seems to be a relatively common pattern (from the tests).

Is there anywhere you can begin to use this other than in the tests? Or is this building up to your proposal on adding register field info to lldb-server?

@DavidSpickett
Copy link
Collaborator Author

Is there anywhere you can begin to use this other than in the tests? Or is this building up to your proposal on adding register field info to lldb-server?

Yes. I'm working on a tree including this that I'll PR bit by bit and that's where it's really key. The rest is testing or the gdb stub doing it all behind the scenes.

So I'll sit on this for a bit until the RFC has settled, thanks for the review so far.

@DavidSpickett
Copy link
Collaborator Author

@bulbazord Ok to land this? (looks like I'll be going ahead with the work presented in the RFC)

Copy link
Member

@bulbazord bulbazord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay, this looks fine to me. I don't have much to say about your RFC (since it's not something I have a lot of expertise on) but I look forward to seeing it get implemented! 😄

@DavidSpickett DavidSpickett merged commit fe92977 into llvm:main Oct 23, 2023
@DavidSpickett DavidSpickett deleted the lldb-single-bit branch October 23, 2023 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants