[Lldb-commits] [PATCH] D16975: Handle floating-point type homogeneous aggregate return values in ABISysV_arm

Muhammad Omair Javaid via lldb-commits lldb-commits at lists.llvm.org
Sun Feb 7 12:57:12 PST 2016


omjavaid created this revision.
omjavaid added reviewers: tberghammer, clayborg.
omjavaid added a subscriber: lldb-commits.
Herald added subscribers: rengolin, aemerson.

Arm hard float ABI can use floating point registers for returning structures containing all 4 or 8 byte floating point elements.

Arm ABI documentation call such structs a Homogeneous Aggregate, which is a Composite Type where all of the Fundamental Data Types that compose the type
are the same.

With Arm Hard float ABI a Homogeneous Aggregate with a Base Type of a single- or double-precision floating-point type with one to four Elements can be returned using register s0-s3 and d0-d3.

This patch updates ABISysV_arm::GetReturnValueObjectImpl to handle these cases.

ReturnValueTestCase passes on armhf based linux target after applying this patch.





http://reviews.llvm.org/D16975

Files:
  source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp

Index: source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
===================================================================
--- source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
+++ source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
@@ -587,6 +587,74 @@
         }
         else
         {
+            if (IsArmHardFloat(thread))
+            {
+                CompilerType base_type;
+                const uint32_t homogeneous_count = compiler_type.IsHomogeneousAggregate (&base_type);
+
+                if (homogeneous_count > 0 && homogeneous_count <= 4)
+                {
+                    if (base_type.IsFloatingPointType(float_count, is_complex))
+                    {
+                        if (!is_complex)
+                        {
+                            ProcessSP process_sp (thread.GetProcess());
+                            ByteOrder byte_order = process_sp->GetByteOrder();
+
+                            DataBufferSP data_sp (new DataBufferHeap(byte_size, 0));
+                            const size_t base_byte_size = base_type.GetByteSize(nullptr);
+                            uint32_t data_offset = 0;
+
+                            for (uint32_t reg_index = 0; reg_index < homogeneous_count; reg_index++)
+                            {
+                                char reg_name[8];
+
+                                if (base_byte_size == 4)
+                                    ::snprintf (reg_name, sizeof(reg_name), "s%u", reg_index);
+                                else if (base_byte_size == 8)
+                                    ::snprintf (reg_name, sizeof(reg_name), "d%u", reg_index);
+                                else
+                                    break;
+
+                                const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name, 0);
+                                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 + base_byte_size) <= data_sp->GetByteSize())
+                                {
+                                    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)
+                                        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);
+                            }
+
+                        }
+                    }
+                }
+            }
+
             if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value))
                 return return_valobj_sp;
         }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D16975.47152.patch
Type: text/x-patch
Size: 3893 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20160207/b4813865/attachment.bin>


More information about the lldb-commits mailing list