Skip to content

[LLDB] Add APFloat helper functions to Scalar class. #86862

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 4 commits into from
Mar 29, 2024

Conversation

cmtice
Copy link
Contributor

@cmtice cmtice commented Mar 27, 2024

This adds the ability to create a Scalar from an APFloat, and to create an APFloat from an APSInt or another APFloat.

This adds the ability to create a Scalar from an APFloat, and to
create an APFloat from an APSInt or another APFloat.
@cmtice cmtice requested a review from JDevlieghere as a code owner March 27, 2024 19:39
@llvmbot llvmbot added the lldb label Mar 27, 2024
@llvmbot
Copy link
Member

llvmbot commented Mar 27, 2024

@llvm/pr-subscribers-lldb

Author: None (cmtice)

Changes

This adds the ability to create a Scalar from an APFloat, and to create an APFloat from an APSInt or another APFloat.


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

2 Files Affected:

  • (modified) lldb/include/lldb/Utility/Scalar.h (+6)
  • (modified) lldb/source/Utility/Scalar.cpp (+42)
diff --git a/lldb/include/lldb/Utility/Scalar.h b/lldb/include/lldb/Utility/Scalar.h
index 8e087a5ddeb855..d5e70fdf203001 100644
--- a/lldb/include/lldb/Utility/Scalar.h
+++ b/lldb/include/lldb/Utility/Scalar.h
@@ -71,6 +71,8 @@ class Scalar {
       : m_type(e_int), m_integer(std::move(v), false), m_float(0.0f) {}
   Scalar(llvm::APSInt v)
       : m_type(e_int), m_integer(std::move(v)), m_float(0.0f) {}
+  Scalar(llvm::APFloat v)
+      : m_integer(0), m_float(v) {}
 
   bool SignExtend(uint32_t bit_pos);
 
@@ -186,6 +188,10 @@ class Scalar {
   Status SetValueFromData(const DataExtractor &data, lldb::Encoding encoding,
                           size_t byte_size);
 
+  llvm::APFloat CreateAPFloatFromAPSInt(lldb::BasicType basic_type);
+
+  llvm::APFloat CreateAPFloatFromAPFloat(lldb::BasicType basic_type);
+
 protected:
   Scalar::Type m_type = e_void;
   llvm::APSInt m_integer;
diff --git a/lldb/source/Utility/Scalar.cpp b/lldb/source/Utility/Scalar.cpp
index 5ad68065bce1b7..afcb204d8f95a5 100644
--- a/lldb/source/Utility/Scalar.cpp
+++ b/lldb/source/Utility/Scalar.cpp
@@ -813,6 +813,48 @@ bool Scalar::ExtractBitfield(uint32_t bit_size, uint32_t bit_offset) {
   return false;
 }
 
+llvm::APFloat Scalar::CreateAPFloatFromAPSInt(lldb::BasicType basic_type) {
+  switch (basic_type) {
+    case lldb::eBasicTypeFloat:
+      return llvm::APFloat(m_integer.isSigned()
+                           ? llvm::APIntOps::RoundSignedAPIntToFloat(m_integer)
+                           : llvm::APIntOps::RoundAPIntToFloat(m_integer));
+    case lldb::eBasicTypeDouble:
+      // No way to get more precision at the moment.
+    case lldb::eBasicTypeLongDouble:
+      return llvm::APFloat(m_integer.isSigned()
+                               ? llvm::APIntOps::RoundSignedAPIntToDouble(
+                                   m_integer)
+                               : llvm::APIntOps::RoundAPIntToDouble(m_integer));
+    default:
+      const llvm::fltSemantics &sem = APFloat::IEEEsingle();
+      return llvm::APFloat::getNaN(sem);
+  }
+}
+
+llvm::APFloat Scalar::CreateAPFloatFromAPFloat(lldb::BasicType basic_type) {
+  switch (basic_type) {
+    case lldb::eBasicTypeFloat: {
+      bool loses_info;
+      m_float.convert(llvm::APFloat::IEEEsingle(),
+                      llvm::APFloat::rmNearestTiesToEven, &loses_info);
+      return m_float;
+    }
+    case lldb::eBasicTypeDouble:
+      // No way to get more precision at the moment.
+    case lldb::eBasicTypeLongDouble: {
+      bool loses_info;
+      m_float.convert(llvm::APFloat::IEEEdouble(),
+                    llvm::APFloat::rmNearestTiesToEven, &loses_info);
+      return m_float;
+    }
+    default:
+      const llvm::fltSemantics &sem = APFloat::IEEEsingle();
+      return llvm::APFloat::getNaN(sem);
+  }
+}
+
+
 bool lldb_private::operator==(Scalar lhs, Scalar rhs) {
   // If either entry is void then we can just compare the types
   if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)

Copy link

github-actions bot commented Mar 27, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

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.

Could you add a test for these new methods in unittests/Utility/ScalarTest.cpp?

@cmtice
Copy link
Contributor Author

cmtice commented Mar 28, 2024

Could you add a test for these new methods in unittests/Utility/ScalarTest.cpp?

Done. :-)

@bulbazord
Copy link
Member

Could you add a test for these new methods in unittests/Utility/ScalarTest.cpp?

Done. :-)

Thank you! :)

@cmtice cmtice merged commit ba6b2d2 into llvm:main Mar 29, 2024
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.

4 participants