[Lldb-commits] [lldb] r262218 - Add/Improve complex, vector, aggregate types handling for SysV ARM (hard/soft) ABI.

Omair Javaid via lldb-commits lldb-commits at lists.llvm.org
Mon Feb 29 05:39:20 PST 2016


Author: omjavaid
Date: Mon Feb 29 07:39:20 2016
New Revision: 262218

URL: http://llvm.org/viewvc/llvm-project?rev=262218&view=rev
Log:
Add/Improve complex, vector, aggregate types handling for SysV ARM (hard/soft) ABI.

For details see:

Differential revision: http://reviews.llvm.org/D17708


Modified:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py
    lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py?rev=262218&r1=262217&r2=262218&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py Mon Feb 29 07:39:20 2016
@@ -151,11 +151,11 @@ class ReturnValueTestCase(TestBase):
         #self.return_and_test_struct_value ("return_one_int_one_double_packed")
         self.return_and_test_struct_value ("return_one_int_one_long")
 
+        self.return_and_test_struct_value ("return_vector_size_float32_8")
+        self.return_and_test_struct_value ("return_vector_size_float32_16")
+        self.return_and_test_struct_value ("return_vector_size_float32_32")
         # icc and gcc don't support this extension.
         if self.getCompiler().endswith('clang'):
-            self.return_and_test_struct_value ("return_vector_size_float32_8")
-            self.return_and_test_struct_value ("return_vector_size_float32_16")
-            self.return_and_test_struct_value ("return_vector_size_float32_32")
             self.return_and_test_struct_value ("return_ext_vector_size_float32_2")
             self.return_and_test_struct_value ("return_ext_vector_size_float32_4")
             self.return_and_test_struct_value ("return_ext_vector_size_float32_8")

Modified: lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp?rev=262218&r1=262217&r2=262218&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp Mon Feb 29 07:39:20 2016
@@ -452,12 +452,16 @@ ABISysV_arm::GetReturnValueObjectImpl (T
     bool is_signed;
     bool is_complex;
     uint32_t float_count;
+    bool is_vfp_candidate = false;
+    uint8_t vfp_count = 0;
+    uint8_t vfp_byte_size = 0;
     
     // Get the pointer to the first stack argument so we have a place to start 
     // when reading data
     
     const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
     size_t bit_width = compiler_type.GetBitSize(&thread);
+    size_t byte_size = compiler_type.GetByteSize(&thread);
 
     if (compiler_type.IsIntegerType (is_signed))
     {       
@@ -504,8 +508,13 @@ ABISysV_arm::GetReturnValueObjectImpl (T
     }
     else if (compiler_type.IsVectorType(nullptr, nullptr))
     {
-        size_t byte_size = compiler_type.GetByteSize(&thread);
-        if (byte_size <= 16)
+        if (IsArmHardFloat(thread) && (byte_size == 8 || byte_size == 16))
+        {
+            is_vfp_candidate = true;
+            vfp_byte_size = 8;
+            vfp_count = (byte_size == 8?1:2);
+        }
+        else if (byte_size <= 16)
         {
             DataBufferHeap buffer(16, 0);
             uint32_t* buffer_ptr = (uint32_t*)buffer.GetBytes();
@@ -574,15 +583,23 @@ ABISysV_arm::GetReturnValueObjectImpl (T
                 }
             }
         }
-        else
+        else if (is_complex && float_count == 2)
         {
+            if (IsArmHardFloat(thread))
+            {
+                is_vfp_candidate = true;
+                vfp_byte_size = byte_size / 2;
+                vfp_count = 2;
+            }
+            else if (!GetReturnValuePassedInMemory(thread, reg_ctx, bit_width / 8, value))
+                return return_valobj_sp;
+        }
+        else
             // not handled yet
             return return_valobj_sp;
-        }
     }
     else if (compiler_type.IsAggregateType())
     {
-        size_t byte_size = compiler_type.GetByteSize(&thread);
         if (IsArmHardFloat(thread))
         {
             CompilerType base_type;
@@ -590,70 +607,59 @@ ABISysV_arm::GetReturnValueObjectImpl (T
 
             if (homogeneous_count > 0 && homogeneous_count <= 4)
             {
-                if (base_type.IsFloatingPointType(float_count, is_complex))
+                if (base_type.IsVectorType(nullptr, nullptr))
+                {
+                    uint64_t base_byte_size = base_type.GetByteSize(nullptr);
+                    if (base_byte_size == 8 || base_byte_size == 16)
+                    {
+                        is_vfp_candidate = true;
+                        vfp_byte_size = 8;
+                        vfp_count = (base_type.GetByteSize(nullptr) == 8 ? homogeneous_count : homogeneous_count * 2);
+                    }
+                }
+                else if (base_type.IsFloatingPointType(float_count, is_complex))
                 {
                     if (float_count == 1 && !is_complex)
                     {
-                        ProcessSP process_sp (thread.GetProcess());
-                        ByteOrder byte_order = process_sp->GetByteOrder();
+                        is_vfp_candidate = true;
+                        vfp_byte_size = base_type.GetByteSize(nullptr);
+                        vfp_count = homogeneous_count;
+                    }
+                }
+            }
+            else if (homogeneous_count == 0)
+            {
+                const uint32_t num_children = compiler_type.GetNumFields ();
 
-                        DataBufferSP data_sp (new DataBufferHeap(byte_size, 0));
-                        const size_t base_byte_size = base_type.GetByteSize(nullptr);
-                        uint32_t data_offset = 0;
+                if (num_children > 0 && num_children <=2)
+                {
+                    uint32_t index = 0;
+                    for (index = 0; index < num_children; index++)
+                    {
+                        std::string name;
+                        base_type = compiler_type.GetFieldAtIndex (index, name, NULL, NULL, NULL);
 
-                        for (uint32_t reg_index = 0; reg_index < homogeneous_count; reg_index++)
+                        if (base_type.IsFloatingPointType(float_count, is_complex))
                         {
-                            uint32_t regnum = 0;
-
-                            if (base_byte_size == 4)
-                                regnum = dwarf_s0 + reg_index;
-                            else if (base_byte_size == 8)
-                                regnum = dwarf_d0 + reg_index;
-                            else
-                                break;
-
-                            const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo (eRegisterKindDWARF, regnum);
-                            if (reg_info == nullptr)
-                                break;
-
-                            RegisterValue reg_value;
-                            if (!reg_ctx->ReadRegister(reg_info, reg_value))
-                                break;
-
-                            // Make sure we have enough room in "data_sp"
-                            if ((data_offset + base_byte_size) <= data_sp->GetByteSize())
+                            if (float_count == 2 && is_complex)
                             {
-                                Error error;
-                                const size_t bytes_copied = reg_value.GetAsMemoryData (reg_info,
-                                                                                       data_sp->GetBytes() + data_offset,
-                                                                                       base_byte_size,
-                                                                                       byte_order,
-                                                                                       error);
-                                if (bytes_copied != base_byte_size)
+                                if (index != 0 && vfp_byte_size != base_type.GetByteSize(nullptr))
                                     break;
-
-                                data_offset += bytes_copied;
+                                else
+                                    vfp_byte_size = base_type.GetByteSize(nullptr);
                             }
-                        }
-
-                        if (data_offset == byte_size)
-                        {
-                            DataExtractor data;
-                            data.SetByteOrder(byte_order);
-                            data.SetAddressByteSize(process_sp->GetAddressByteSize());
-                            data.SetData(data_sp);
-
-                            return ValueObjectConstResult::Create (&thread, compiler_type, ConstString(""), data);
+                            else
+                                break;
                         }
                         else
-                        {   // Some error occurred while getting values from registers
-                            return return_valobj_sp;
-                        }
-
+                            break;
                     }
-                    else
-                    {   // TODO: Add code to handle complex and vector types.
-                        return return_valobj_sp;
+
+                    if (index == num_children)
+                    {
+                        is_vfp_candidate = true;
+                        vfp_byte_size = (vfp_byte_size >> 1);
+                        vfp_count = (num_children << 1);
                     }
                 }
             }
@@ -665,7 +671,7 @@ ABISysV_arm::GetReturnValueObjectImpl (T
             uint32_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
             value.SetBytes(&raw_value, byte_size);
         }
-        else
+        else if (!is_vfp_candidate)
         {
             if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value))
                 return return_valobj_sp;
@@ -677,6 +683,64 @@ ABISysV_arm::GetReturnValueObjectImpl (T
         return return_valobj_sp;
     }
     
+    if (is_vfp_candidate)
+    {
+        ProcessSP process_sp (thread.GetProcess());
+        ByteOrder byte_order = process_sp->GetByteOrder();
+
+        DataBufferSP data_sp (new DataBufferHeap(byte_size, 0));
+        uint32_t data_offset = 0;
+
+        for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++)
+        {
+            uint32_t regnum = 0;
+
+            if (vfp_byte_size == 4)
+                regnum = dwarf_s0 + reg_index;
+            else if (vfp_byte_size == 8)
+                regnum = dwarf_d0 + reg_index;
+            else
+                break;
+
+            const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo (eRegisterKindDWARF, regnum);
+            if (reg_info == NULL)
+                break;
+
+            RegisterValue reg_value;
+            if (!reg_ctx->ReadRegister(reg_info, reg_value))
+                break;
+
+            // Make sure we have enough room in "data_sp"
+            if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize())
+            {
+                Error error;
+                const size_t bytes_copied = reg_value.GetAsMemoryData (reg_info,
+                                                                       data_sp->GetBytes() + data_offset,
+                                                                       vfp_byte_size,
+                                                                       byte_order,
+                                                                       error);
+                if (bytes_copied != vfp_byte_size)
+                    break;
+
+                data_offset += bytes_copied;
+            }
+        }
+
+        if (data_offset == byte_size)
+        {
+            DataExtractor data;
+            data.SetByteOrder(byte_order);
+            data.SetAddressByteSize(process_sp->GetAddressByteSize());
+            data.SetData(data_sp);
+
+            return ValueObjectConstResult::Create (&thread, compiler_type, ConstString(""), data);
+        }
+        else
+        {   // Some error occurred while getting values from registers
+            return return_valobj_sp;
+        }
+    }
+
     // If we get here, we have a valid Value, so make our ValueObject out of it:
     
     return_valobj_sp = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),




More information about the lldb-commits mailing list