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
This commit is contained in:
parent
d12f31535a
commit
62498ff8f5
|
|
@ -579,6 +579,82 @@ ABISysV_arm::GetReturnValueObjectImpl (Thread &thread,
|
||||||
else if (compiler_type.IsAggregateType())
|
else if (compiler_type.IsAggregateType())
|
||||||
{
|
{
|
||||||
size_t byte_size = compiler_type.GetByteSize(&thread);
|
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)
|
if (byte_size <= 4)
|
||||||
{
|
{
|
||||||
RegisterValue r0_reg_value;
|
RegisterValue r0_reg_value;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue