diff options
| author | Omair Javaid <omair.javaid@linaro.org> | 2016-02-11 11:41:22 +0000 |
|---|---|---|
| committer | Omair Javaid <omair.javaid@linaro.org> | 2016-02-11 11:41:22 +0000 |
| commit | 62498ff8f5fa0e232e33da9cb7a9aa86b51c40f9 (patch) | |
| tree | 106f71118dd69e7f0cd1f8b574c78782e09b8941 | |
| parent | d12f31535a62062ed1b2c6ecf344117ee37e1792 (diff) | |
| download | bcm5719-llvm-62498ff8f5fa0e232e33da9cb7a9aa86b51c40f9.tar.gz bcm5719-llvm-62498ff8f5fa0e232e33da9cb7a9aa86b51c40f9.zip | |
Handle floating-point type homogeneous aggregate return values in ABISysV_arm
For details refer to review link given below.
Differential revision: http://reviews.llvm.org/D16975
llvm-svn: 260512
| -rw-r--r-- | lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp index 14e49ef5991..f317bf3a7c3 100644 --- a/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp +++ b/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp @@ -579,6 +579,82 @@ ABISysV_arm::GetReturnValueObjectImpl (Thread &thread, else if (compiler_type.IsAggregateType()) { size_t byte_size = compiler_type.GetByteSize(&thread); + 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 (float_count == 1 && !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++) + { + 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 == 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); + } + else + { // Some error occurred while getting values from registers + return return_valobj_sp; + } + + } + else + { // TODO: Add code to handle complex and vector types. + return return_valobj_sp; + } + } + } + } + if (byte_size <= 4) { RegisterValue r0_reg_value; |

