2010-06-09 00:52:24 +08:00
|
|
|
//===-- Scalar.cpp ----------------------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "lldb/Core/Scalar.h"
|
|
|
|
|
2016-03-12 08:31:13 +08:00
|
|
|
// C Includes
|
|
|
|
// C++ Includes
|
|
|
|
#include <cinttypes>
|
|
|
|
#include <cmath>
|
|
|
|
#include <cstdio>
|
|
|
|
|
|
|
|
// Other libraries and framework includes
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
#include "llvm/ADT/SmallString.h"
|
|
|
|
|
2016-03-12 08:31:13 +08:00
|
|
|
// Project includes
|
2010-06-16 03:49:27 +08:00
|
|
|
#include "lldb/Interpreter/Args.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Core/Error.h"
|
|
|
|
#include "lldb/Core/Stream.h"
|
|
|
|
#include "lldb/Core/DataExtractor.h"
|
2011-02-01 09:31:41 +08:00
|
|
|
#include "lldb/Host/Endian.h"
|
2015-01-16 04:08:35 +08:00
|
|
|
#include "lldb/Host/StringConvert.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2011-12-29 09:26:56 +08:00
|
|
|
#include "Plugins/Process/Utility/InstructionUtils.h"
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Promote to max type currently follows the ANSI C rule for type
|
|
|
|
// promotion in expressions.
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
static Scalar::Type
|
|
|
|
PromoteToMaxType
|
|
|
|
(
|
|
|
|
const Scalar& lhs, // The const left hand side object
|
|
|
|
const Scalar& rhs, // The const right hand side object
|
|
|
|
Scalar& temp_value, // A modifiable temp value than can be used to hold either the promoted lhs or rhs object
|
|
|
|
const Scalar* &promoted_lhs_ptr, // Pointer to the resulting possibly promoted value of lhs (at most one of lhs/rhs will get promoted)
|
|
|
|
const Scalar* &promoted_rhs_ptr // Pointer to the resulting possibly promoted value of rhs (at most one of lhs/rhs will get promoted)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
Scalar result;
|
|
|
|
// Initialize the promoted values for both the right and left hand side values
|
|
|
|
// to be the objects themselves. If no promotion is needed (both right and left
|
|
|
|
// have the same type), then the temp_value will not get used.
|
|
|
|
promoted_lhs_ptr = &lhs;
|
|
|
|
promoted_rhs_ptr = &rhs;
|
|
|
|
// Extract the types of both the right and left hand side values
|
|
|
|
Scalar::Type lhs_type = lhs.GetType();
|
|
|
|
Scalar::Type rhs_type = rhs.GetType();
|
|
|
|
|
|
|
|
if (lhs_type > rhs_type)
|
|
|
|
{
|
|
|
|
// Right hand side need to be promoted
|
|
|
|
temp_value = rhs; // Copy right hand side into the temp value
|
|
|
|
if (temp_value.Promote(lhs_type)) // Promote it
|
|
|
|
promoted_rhs_ptr = &temp_value; // Update the pointer for the promoted right hand side
|
|
|
|
}
|
|
|
|
else if (lhs_type < rhs_type)
|
|
|
|
{
|
|
|
|
// Left hand side need to be promoted
|
|
|
|
temp_value = lhs; // Copy left hand side value into the temp value
|
|
|
|
if (temp_value.Promote(rhs_type)) // Promote it
|
|
|
|
promoted_lhs_ptr = &temp_value; // Update the pointer for the promoted left hand side
|
|
|
|
}
|
|
|
|
|
2014-07-02 05:22:11 +08:00
|
|
|
// Make sure our type promotion worked as expected
|
2010-06-09 00:52:24 +08:00
|
|
|
if (promoted_lhs_ptr->GetType() == promoted_rhs_ptr->GetType())
|
|
|
|
return promoted_lhs_ptr->GetType(); // Return the resulting max type
|
|
|
|
|
|
|
|
// Return the void type (zero) if we fail to promote either of the values.
|
|
|
|
return Scalar::e_void;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar::Scalar() :
|
|
|
|
m_type(e_void),
|
2015-08-20 17:12:46 +08:00
|
|
|
m_float((float)0)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar::Scalar(const Scalar& rhs) :
|
|
|
|
m_type(rhs.m_type),
|
2015-08-20 17:12:46 +08:00
|
|
|
m_integer(rhs.m_integer),
|
|
|
|
m_float(rhs.m_float)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//Scalar::Scalar(const RegisterValue& reg) :
|
|
|
|
// m_type(e_void),
|
|
|
|
// m_data()
|
|
|
|
//{
|
|
|
|
// switch (reg.info.encoding)
|
|
|
|
// {
|
|
|
|
// case eEncodingUint: // unsigned integer
|
|
|
|
// switch (reg.info.byte_size)
|
|
|
|
// {
|
|
|
|
// case 1: m_type = e_uint; m_data.uint = reg.value.uint8; break;
|
|
|
|
// case 2: m_type = e_uint; m_data.uint = reg.value.uint16; break;
|
|
|
|
// case 4: m_type = e_uint; m_data.uint = reg.value.uint32; break;
|
|
|
|
// case 8: m_type = e_ulonglong; m_data.ulonglong = reg.value.uint64; break;
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// break;
|
|
|
|
//
|
|
|
|
// case eEncodingSint: // signed integer
|
|
|
|
// switch (reg.info.byte_size)
|
|
|
|
// {
|
|
|
|
// case 1: m_type = e_sint; m_data.sint = reg.value.sint8; break;
|
|
|
|
// case 2: m_type = e_sint; m_data.sint = reg.value.sint16; break;
|
|
|
|
// case 4: m_type = e_sint; m_data.sint = reg.value.sint32; break;
|
|
|
|
// case 8: m_type = e_slonglong; m_data.slonglong = reg.value.sint64; break;
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// break;
|
|
|
|
//
|
|
|
|
// case eEncodingIEEE754: // float
|
|
|
|
// switch (reg.info.byte_size)
|
|
|
|
// {
|
|
|
|
// case 4: m_type = e_float; m_data.flt = reg.value.float32; break;
|
|
|
|
// case 8: m_type = e_double; m_data.dbl = reg.value.float64; break;
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// break;
|
|
|
|
// case eEncodingVector: // vector registers
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Scalar::GetData (DataExtractor &data, size_t limit_byte_size) const
|
|
|
|
{
|
|
|
|
size_t byte_size = GetByteSize();
|
|
|
|
if (byte_size > 0)
|
|
|
|
{
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
const uint8_t *bytes = reinterpret_cast<const uint8_t *>(GetBytes());
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (limit_byte_size < byte_size)
|
|
|
|
{
|
2015-11-07 12:40:13 +08:00
|
|
|
if (endian::InlHostByteOrder() == eByteOrderLittle)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
// On little endian systems if we want fewer bytes from the
|
|
|
|
// current type we just specify fewer bytes since the LSByte
|
|
|
|
// is first...
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
byte_size = limit_byte_size;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2015-11-07 12:40:13 +08:00
|
|
|
else if (endian::InlHostByteOrder() == eByteOrderBig)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
// On big endian systems if we want fewer bytes from the
|
|
|
|
// current type have to advance our initial byte pointer and
|
|
|
|
// trim down the number of bytes since the MSByte is first
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
bytes += byte_size - limit_byte_size;
|
|
|
|
byte_size = limit_byte_size;
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
|
|
|
|
data.SetData(bytes, byte_size, endian::InlHostByteOrder());
|
2010-06-09 00:52:24 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
data.Clear();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
Make Scalar::GetBytes and RegisterValue::GetBytes const
Scalar::GetBytes provides a non-const access to the underlying bytes
of the scalar value, supposedly allowing for modification of those
bytes. However, even with the current implementation, this is not
really possible. For floating-point scalars, the pointer returned
by GetBytes refers to a temporary copy; modifications to that copy
will be simply ignored. For integer scalars, the pointer refers
to internal memory of the APInt implementation, which isn't
supposed to be directly modifyable; GetBytes simply casts aways
the const-ness of the pointer ...
With my upcoming patch to fix Scalar::GetBytes for big-endian
systems, this problem is going to get worse, since there we need
temporary copies even for some integer scalars. Therefore, this
patch makes Scalar::GetBytes const, fixing all those problems.
As a follow-on change, RegisterValues::GetBytes must be made const
as well. This in turn means that the way of initializing a
RegisterValue by doing a SetType followed by writing to GetBytes
no longer works. Instead, I've changed SetValueFromData to do
the equivalent of SetType itself, and then re-implemented
SetFromMemoryData to work on top of SetValueFromData.
There is still a need for RegisterValue::SetType, since some
platform-specific code uses it to reinterpret the contents of
an already filled RegisterValue. To make this usage work in
all cases (even changing from a type implemented via Scalar
to a type implemented as a byte buffer), SetType now simply
copies the old contents out, and then reloads the RegisterValue
from this data using the new type via SetValueFromData.
This in turn means that there is no remaining caller of
Scalar::SetType, so it can be removed.
The only other follow-on change was in MIPS EmulateInstruction
code, where some uses of RegisterValue::GetBytes could be made
const trivially.
Differential Revision: http://reviews.llvm.org/D18980
llvm-svn: 266310
2016-04-14 22:31:08 +08:00
|
|
|
const void *
|
2015-08-20 17:12:46 +08:00
|
|
|
Scalar::GetBytes() const
|
|
|
|
{
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
const uint64_t *apint_words;
|
|
|
|
const uint8_t *bytes;
|
2015-08-20 17:12:46 +08:00
|
|
|
static float_t flt_val;
|
|
|
|
static double_t dbl_val;
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
static uint64_t swapped_words[4];
|
2015-08-20 17:12:46 +08:00
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
bytes = reinterpret_cast<const uint8_t *>(m_integer.getRawData());
|
|
|
|
// getRawData always returns a pointer to an uint64_t. If we have a smaller type,
|
|
|
|
// we need to update the pointer on big-endian systems.
|
|
|
|
if (endian::InlHostByteOrder() == eByteOrderBig)
|
|
|
|
{
|
|
|
|
size_t byte_size = m_integer.getBitWidth() / 8;
|
|
|
|
if (byte_size < 8)
|
|
|
|
bytes += 8 - byte_size;
|
|
|
|
}
|
|
|
|
return bytes;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
apint_words = m_integer.getRawData();
|
|
|
|
// getRawData always returns a pointer to an array of two uint64_t values,
|
|
|
|
// where the least-significant word always comes first. On big-endian
|
|
|
|
// systems we need to swap the two words.
|
|
|
|
if (endian::InlHostByteOrder() == eByteOrderBig)
|
|
|
|
{
|
|
|
|
swapped_words[0] = apint_words[1];
|
|
|
|
swapped_words[1] = apint_words[0];
|
|
|
|
apint_words = swapped_words;
|
|
|
|
}
|
|
|
|
return reinterpret_cast<const void *>(apint_words);
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
apint_words = m_integer.getRawData();
|
|
|
|
// getRawData always returns a pointer to an array of four uint64_t values,
|
|
|
|
// where the least-significant word always comes first. On big-endian
|
|
|
|
// systems we need to swap the four words.
|
|
|
|
if (endian::InlHostByteOrder() == eByteOrderBig)
|
|
|
|
{
|
|
|
|
swapped_words[0] = apint_words[3];
|
|
|
|
swapped_words[1] = apint_words[2];
|
|
|
|
swapped_words[2] = apint_words[1];
|
|
|
|
swapped_words[3] = apint_words[0];
|
|
|
|
apint_words = swapped_words;
|
|
|
|
}
|
|
|
|
return reinterpret_cast<const void *>(apint_words);
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
flt_val = m_float.convertToFloat();
|
Make Scalar::GetBytes and RegisterValue::GetBytes const
Scalar::GetBytes provides a non-const access to the underlying bytes
of the scalar value, supposedly allowing for modification of those
bytes. However, even with the current implementation, this is not
really possible. For floating-point scalars, the pointer returned
by GetBytes refers to a temporary copy; modifications to that copy
will be simply ignored. For integer scalars, the pointer refers
to internal memory of the APInt implementation, which isn't
supposed to be directly modifyable; GetBytes simply casts aways
the const-ness of the pointer ...
With my upcoming patch to fix Scalar::GetBytes for big-endian
systems, this problem is going to get worse, since there we need
temporary copies even for some integer scalars. Therefore, this
patch makes Scalar::GetBytes const, fixing all those problems.
As a follow-on change, RegisterValues::GetBytes must be made const
as well. This in turn means that the way of initializing a
RegisterValue by doing a SetType followed by writing to GetBytes
no longer works. Instead, I've changed SetValueFromData to do
the equivalent of SetType itself, and then re-implemented
SetFromMemoryData to work on top of SetValueFromData.
There is still a need for RegisterValue::SetType, since some
platform-specific code uses it to reinterpret the contents of
an already filled RegisterValue. To make this usage work in
all cases (even changing from a type implemented via Scalar
to a type implemented as a byte buffer), SetType now simply
copies the old contents out, and then reloads the RegisterValue
from this data using the new type via SetValueFromData.
This in turn means that there is no remaining caller of
Scalar::SetType, so it can be removed.
The only other follow-on change was in MIPS EmulateInstruction
code, where some uses of RegisterValue::GetBytes could be made
const trivially.
Differential Revision: http://reviews.llvm.org/D18980
llvm-svn: 266310
2016-04-14 22:31:08 +08:00
|
|
|
return reinterpret_cast<const void *>(&flt_val);
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_double:
|
|
|
|
dbl_val = m_float.convertToDouble();
|
Make Scalar::GetBytes and RegisterValue::GetBytes const
Scalar::GetBytes provides a non-const access to the underlying bytes
of the scalar value, supposedly allowing for modification of those
bytes. However, even with the current implementation, this is not
really possible. For floating-point scalars, the pointer returned
by GetBytes refers to a temporary copy; modifications to that copy
will be simply ignored. For integer scalars, the pointer refers
to internal memory of the APInt implementation, which isn't
supposed to be directly modifyable; GetBytes simply casts aways
the const-ness of the pointer ...
With my upcoming patch to fix Scalar::GetBytes for big-endian
systems, this problem is going to get worse, since there we need
temporary copies even for some integer scalars. Therefore, this
patch makes Scalar::GetBytes const, fixing all those problems.
As a follow-on change, RegisterValues::GetBytes must be made const
as well. This in turn means that the way of initializing a
RegisterValue by doing a SetType followed by writing to GetBytes
no longer works. Instead, I've changed SetValueFromData to do
the equivalent of SetType itself, and then re-implemented
SetFromMemoryData to work on top of SetValueFromData.
There is still a need for RegisterValue::SetType, since some
platform-specific code uses it to reinterpret the contents of
an already filled RegisterValue. To make this usage work in
all cases (even changing from a type implemented via Scalar
to a type implemented as a byte buffer), SetType now simply
copies the old contents out, and then reloads the RegisterValue
from this data using the new type via SetValueFromData.
This in turn means that there is no remaining caller of
Scalar::SetType, so it can be removed.
The only other follow-on change was in MIPS EmulateInstruction
code, where some uses of RegisterValue::GetBytes could be made
const trivially.
Differential Revision: http://reviews.llvm.org/D18980
llvm-svn: 266310
2016-04-14 22:31:08 +08:00
|
|
|
return reinterpret_cast<const void *>(&dbl_val);
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
apint_words = ldbl_val.getRawData();
|
|
|
|
// getRawData always returns a pointer to an array of two uint64_t values,
|
|
|
|
// where the least-significant word always comes first. On big-endian
|
|
|
|
// systems we need to swap the two words.
|
|
|
|
if (endian::InlHostByteOrder() == eByteOrderBig)
|
|
|
|
{
|
|
|
|
swapped_words[0] = apint_words[1];
|
|
|
|
swapped_words[1] = apint_words[0];
|
|
|
|
apint_words = swapped_words;
|
|
|
|
}
|
|
|
|
return reinterpret_cast<const void *>(apint_words);
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
2016-03-12 08:31:13 +08:00
|
|
|
return nullptr;
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
size_t
|
|
|
|
Scalar::GetByteSize() const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint128:
|
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
|
|
|
return (m_integer.getBitWidth() / 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float: return sizeof(float_t);
|
|
|
|
case e_double: return sizeof(double_t);
|
|
|
|
case e_long_double: return sizeof(long_double_t);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Scalar::IsZero() const
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
llvm::APInt zero_int = llvm::APInt::getNullValue(m_integer.getBitWidth() / 8);
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return llvm::APInt::isSameValue(zero_int, m_integer);
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
return m_float.isZero();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Scalar::GetValue (Stream *s, bool show_type) const
|
|
|
|
{
|
|
|
|
if (show_type)
|
|
|
|
s->Printf("(%s) ", GetTypeAsCString());
|
|
|
|
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
break;
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
s->Printf("%s",m_integer.toString(10,true).c_str());
|
2015-08-20 17:12:46 +08:00
|
|
|
break;
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
|
|
|
s->Printf("%s",m_integer.toString(16,false).c_str());
|
|
|
|
break;
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
case e_float:
|
|
|
|
case e_double:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
llvm::SmallString<24> string;
|
|
|
|
m_float.toString(string);
|
|
|
|
s->Printf("%s", string.c_str());
|
2015-08-20 17:12:46 +08:00
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
Scalar::GetTypeAsCString() const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: return "void";
|
|
|
|
case e_sint: return "int";
|
|
|
|
case e_uint: return "unsigned int";
|
|
|
|
case e_slong: return "long";
|
|
|
|
case e_ulong: return "unsigned long";
|
|
|
|
case e_slonglong: return "long long";
|
|
|
|
case e_ulonglong: return "unsigned long long";
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128: return "int128_t";
|
|
|
|
case e_uint128: return "unsigned int128_t";
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256: return "int256_t";
|
|
|
|
case e_uint256: return "unsigned int256_t";
|
2010-06-09 00:52:24 +08:00
|
|
|
case e_float: return "float";
|
|
|
|
case e_double: return "double";
|
|
|
|
case e_long_double: return "long double";
|
|
|
|
}
|
|
|
|
return "<invalid Scalar type>";
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator=(const Scalar& rhs)
|
|
|
|
{
|
|
|
|
if (this != &rhs)
|
|
|
|
{
|
|
|
|
m_type = rhs.m_type;
|
2015-08-20 17:12:46 +08:00
|
|
|
m_integer = llvm::APInt(rhs.m_integer);
|
|
|
|
m_float = rhs.m_float;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator= (const int v)
|
|
|
|
{
|
|
|
|
m_type = e_sint;
|
2015-08-20 17:12:46 +08:00
|
|
|
m_integer = llvm::APInt(sizeof(int) * 8, v, true);
|
2010-06-09 00:52:24 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator= (unsigned int v)
|
|
|
|
{
|
|
|
|
m_type = e_uint;
|
2015-08-20 17:12:46 +08:00
|
|
|
m_integer = llvm::APInt(sizeof(int) * 8, v);
|
2010-06-09 00:52:24 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator= (long v)
|
|
|
|
{
|
|
|
|
m_type = e_slong;
|
2015-08-20 17:12:46 +08:00
|
|
|
m_integer = llvm::APInt(sizeof(long) * 8, v, true);
|
2010-06-09 00:52:24 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator= (unsigned long v)
|
|
|
|
{
|
|
|
|
m_type = e_ulong;
|
2015-08-20 17:12:46 +08:00
|
|
|
m_integer = llvm::APInt(sizeof(long) * 8, v);
|
2010-06-09 00:52:24 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator= (long long v)
|
|
|
|
{
|
|
|
|
m_type = e_slonglong;
|
2015-08-20 17:12:46 +08:00
|
|
|
m_integer = llvm::APInt(sizeof(long) * 8, v, true);
|
2010-06-09 00:52:24 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator= (unsigned long long v)
|
|
|
|
{
|
|
|
|
m_type = e_ulonglong;
|
2015-08-20 17:12:46 +08:00
|
|
|
m_integer = llvm::APInt(sizeof(long long) * 8, v);
|
2010-06-09 00:52:24 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator= (float v)
|
|
|
|
{
|
|
|
|
m_type = e_float;
|
2015-08-20 17:12:46 +08:00
|
|
|
m_float = llvm::APFloat(v);
|
2010-06-09 00:52:24 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator= (double v)
|
|
|
|
{
|
|
|
|
m_type = e_double;
|
2015-08-20 17:12:46 +08:00
|
|
|
m_float = llvm::APFloat(v);
|
2010-06-09 00:52:24 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator= (long double v)
|
|
|
|
{
|
|
|
|
m_type = e_long_double;
|
2015-08-20 17:12:46 +08:00
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&v)->x));
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&v)->x));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator= (llvm::APInt rhs)
|
|
|
|
{
|
|
|
|
m_integer = llvm::APInt(rhs);
|
|
|
|
switch(m_integer.getBitWidth())
|
|
|
|
{
|
|
|
|
case 8:
|
|
|
|
case 16:
|
|
|
|
case 32:
|
|
|
|
if(m_integer.isSignedIntN(sizeof(sint_t) * 8))
|
|
|
|
m_type = e_sint;
|
|
|
|
else
|
|
|
|
m_type = e_uint;
|
|
|
|
break;
|
|
|
|
case 64:
|
|
|
|
if(m_integer.isSignedIntN(sizeof(slonglong_t) * 8))
|
|
|
|
m_type = e_slonglong;
|
|
|
|
else
|
|
|
|
m_type = e_ulonglong;
|
|
|
|
break;
|
|
|
|
case 128:
|
|
|
|
if(m_integer.isSignedIntN(BITWIDTH_INT128))
|
|
|
|
m_type = e_sint128;
|
|
|
|
else
|
|
|
|
m_type = e_uint128;
|
|
|
|
break;
|
2016-03-10 08:14:29 +08:00
|
|
|
case 256:
|
|
|
|
if(m_integer.isSignedIntN(BITWIDTH_INT256))
|
|
|
|
m_type = e_sint256;
|
|
|
|
else
|
|
|
|
m_type = e_uint256;
|
|
|
|
break;
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-03-12 08:31:13 +08:00
|
|
|
Scalar::~Scalar() = default;
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
bool
|
|
|
|
Scalar::Promote(Scalar::Type type)
|
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
break;
|
|
|
|
|
2015-08-11 05:49:50 +08:00
|
|
|
case e_sint:
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void: break;
|
|
|
|
case e_sint: success = true; break;
|
|
|
|
case e_uint:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(uint_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_slong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_ulong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_slonglong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_ulonglong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
|
2016-03-10 08:14:29 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToDouble());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
|
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_uint:
|
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void:
|
|
|
|
case e_sint: break;
|
|
|
|
case e_uint: success = true; break;
|
|
|
|
case e_slong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_ulong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_slonglong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_ulonglong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
|
2016-03-10 08:14:29 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_float:
|
2015-08-20 17:12:46 +08:00
|
|
|
m_float = llvm::APFloat(m_integer.bitsToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToDouble());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
|
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_slong:
|
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void:
|
|
|
|
case e_sint:
|
|
|
|
case e_uint: break;
|
|
|
|
case e_slong: success = true; break;
|
|
|
|
case e_ulong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_slonglong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_ulonglong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
|
2016-03-10 08:14:29 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToDouble());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
|
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_ulong:
|
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void:
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong: break;
|
|
|
|
case e_ulong: success = true; break;
|
|
|
|
case e_slonglong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_ulonglong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
|
2016-03-10 08:14:29 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToDouble());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
|
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_slonglong:
|
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void:
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong: break;
|
|
|
|
case e_slonglong: success = true; break;
|
|
|
|
case e_ulonglong:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
|
2016-03-10 08:14:29 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToDouble());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
|
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_ulonglong:
|
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void:
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong: break;
|
|
|
|
case e_ulonglong: success = true; break;
|
|
|
|
case e_sint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
|
2016-03-10 08:14:29 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToDouble());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_sint128:
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong: break;
|
|
|
|
case e_sint128: success = true; break;
|
|
|
|
case e_uint128:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
|
2015-08-20 17:12:46 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
|
2016-03-10 08:14:29 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToDouble());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_uint128:
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128: break;
|
|
|
|
case e_uint128: success = true; break;
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
|
2016-03-10 08:14:29 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToDouble());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
|
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128: break;
|
|
|
|
case e_sint256: success = true; break;
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
|
2016-03-10 08:14:29 +08:00
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_float:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToDouble());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_uint256:
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
|
|
|
case e_sint256: break;
|
|
|
|
case e_uint256: success = true; break;
|
|
|
|
case e_float:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToDouble());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
|
|
|
|
success = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
case e_float:
|
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void:
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint128:
|
|
|
|
case e_sint256:
|
|
|
|
case e_uint256: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float: success = true; break;
|
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat((float_t)m_float.convertToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt());
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt());
|
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_double:
|
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void:
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float: break;
|
|
|
|
case e_double: success = true; break;
|
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt());
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt());
|
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_long_double:
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2010-06-09 00:52:24 +08:00
|
|
|
case e_float:
|
|
|
|
case e_double: break;
|
|
|
|
case e_long_double: success = true; break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
m_type = type;
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
Scalar::GetValueTypeAsCString (Scalar::Type type)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case e_void: return "void";
|
|
|
|
case e_sint: return "int";
|
|
|
|
case e_uint: return "unsigned int";
|
|
|
|
case e_slong: return "long";
|
|
|
|
case e_ulong: return "unsigned long";
|
|
|
|
case e_slonglong: return "long long";
|
|
|
|
case e_ulonglong: return "unsigned long long";
|
|
|
|
case e_float: return "float";
|
|
|
|
case e_double: return "double";
|
|
|
|
case e_long_double: return "long double";
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128: return "int128_t";
|
|
|
|
case e_uint128: return "uint128_t";
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256: return "int256_t";
|
|
|
|
case e_uint256: return "uint256_t";
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return "???";
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar::Type
|
|
|
|
Scalar::GetValueTypeForSignedIntegerWithByteSize (size_t byte_size)
|
|
|
|
{
|
2013-01-26 02:06:21 +08:00
|
|
|
if (byte_size <= sizeof(sint_t))
|
2010-06-09 00:52:24 +08:00
|
|
|
return e_sint;
|
2013-01-26 02:06:21 +08:00
|
|
|
if (byte_size <= sizeof(slong_t))
|
2010-06-09 00:52:24 +08:00
|
|
|
return e_slong;
|
2013-01-26 02:06:21 +08:00
|
|
|
if (byte_size <= sizeof(slonglong_t))
|
2010-06-09 00:52:24 +08:00
|
|
|
return e_slonglong;
|
|
|
|
return e_void;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar::Type
|
|
|
|
Scalar::GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size)
|
|
|
|
{
|
2013-01-26 02:06:21 +08:00
|
|
|
if (byte_size <= sizeof(uint_t))
|
2010-06-09 00:52:24 +08:00
|
|
|
return e_uint;
|
2013-01-26 02:06:21 +08:00
|
|
|
if (byte_size <= sizeof(ulong_t))
|
2010-06-09 00:52:24 +08:00
|
|
|
return e_ulong;
|
2013-01-26 02:06:21 +08:00
|
|
|
if (byte_size <= sizeof(ulonglong_t))
|
2010-06-09 00:52:24 +08:00
|
|
|
return e_ulonglong;
|
|
|
|
return e_void;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar::Type
|
|
|
|
Scalar::GetValueTypeForFloatWithByteSize (size_t byte_size)
|
|
|
|
{
|
2013-01-26 02:06:21 +08:00
|
|
|
if (byte_size == sizeof(float_t))
|
2010-06-09 00:52:24 +08:00
|
|
|
return e_float;
|
2013-01-26 02:06:21 +08:00
|
|
|
if (byte_size == sizeof(double_t))
|
2010-06-09 00:52:24 +08:00
|
|
|
return e_double;
|
2013-01-26 02:06:21 +08:00
|
|
|
if (byte_size == sizeof(long_double_t))
|
2010-06-09 00:52:24 +08:00
|
|
|
return e_long_double;
|
|
|
|
return e_void;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Scalar::Cast(Scalar::Type type)
|
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_sint:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint:
|
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(sint_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_slong:
|
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_ulong:
|
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_slonglong:
|
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_ulonglong:
|
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint128:
|
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToFloat());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_double:
|
|
|
|
m_float = llvm::APFloat(m_integer.bitsToDouble());
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
|
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint128:
|
|
|
|
case e_sint256:
|
|
|
|
case e_uint256: m_integer = m_float.bitcastToAPInt(); success = true; break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break;
|
|
|
|
case e_double: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break;
|
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt());
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt());
|
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_double:
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint128:
|
|
|
|
case e_sint256:
|
|
|
|
case e_uint256: m_integer = m_float.bitcastToAPInt(); success = true; break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float: m_float = llvm::APFloat(m_float.convertToDouble()); success = true; break;
|
|
|
|
case e_double: m_float = llvm::APFloat(m_float.convertToDouble()); success = true; break;
|
|
|
|
case e_long_double:
|
|
|
|
if(m_ieee_quad)
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt());
|
|
|
|
else
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt());
|
|
|
|
success = true;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_long_double:
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
m_integer = m_float.bitcastToAPInt();
|
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint:
|
|
|
|
m_integer = m_float.bitcastToAPInt();
|
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(sint_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_slong:
|
|
|
|
m_integer = m_float.bitcastToAPInt();
|
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_ulong:
|
|
|
|
m_integer = m_float.bitcastToAPInt();
|
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_slonglong:
|
|
|
|
m_integer = m_float.bitcastToAPInt();
|
|
|
|
m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_ulonglong:
|
|
|
|
m_integer = m_float.bitcastToAPInt();
|
|
|
|
m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
|
|
|
m_integer = m_float.bitcastToAPInt();
|
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint128:
|
|
|
|
m_integer = m_float.bitcastToAPInt();
|
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
m_integer = m_float.bitcastToAPInt();
|
|
|
|
m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
|
|
|
m_integer = m_float.bitcastToAPInt();
|
|
|
|
m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
|
|
|
|
success = true;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break;
|
|
|
|
case e_double: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break;
|
2010-06-09 00:52:24 +08:00
|
|
|
case e_long_double: success = true; break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
m_type = type;
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
2013-05-25 04:36:56 +08:00
|
|
|
bool
|
|
|
|
Scalar::MakeSigned ()
|
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
|
|
|
case e_sint: success = true; break;
|
|
|
|
case e_uint: m_type = e_sint; success = true; break;
|
|
|
|
case e_slong: success = true; break;
|
|
|
|
case e_ulong: m_type = e_slong; success = true; break;
|
|
|
|
case e_slonglong: success = true; break;
|
|
|
|
case e_ulonglong: m_type = e_slonglong; success = true; break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128: success = true; break;
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
case e_uint128: m_type = e_sint128; success = true; break;
|
|
|
|
case e_sint256: success = true; break;
|
|
|
|
case e_uint256: m_type = e_sint256; success = true; break;
|
|
|
|
case e_float: success = true; break;
|
|
|
|
case e_double: success = true; break;
|
|
|
|
case e_long_double: success = true; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Scalar::MakeUnsigned ()
|
|
|
|
{
|
|
|
|
bool success = false;
|
|
|
|
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
|
|
|
case e_sint: success = true; break;
|
|
|
|
case e_uint: m_type = e_uint; success = true; break;
|
|
|
|
case e_slong: success = true; break;
|
|
|
|
case e_ulong: m_type = e_ulong; success = true; break;
|
|
|
|
case e_slonglong: success = true; break;
|
|
|
|
case e_ulonglong: m_type = e_ulonglong; success = true; break;
|
|
|
|
case e_sint128: success = true; break;
|
|
|
|
case e_uint128: m_type = e_uint128; success = true; break;
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256: success = true; break;
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
case e_uint256: m_type = e_uint256; success = true; break;
|
2013-05-25 04:36:56 +08:00
|
|
|
case e_float: success = true; break;
|
|
|
|
case e_double: success = true; break;
|
|
|
|
case e_long_double: success = true; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
signed char
|
2015-08-20 17:12:46 +08:00
|
|
|
Scalar::SChar(char fail_value) const
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (schar_t)(m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
return (schar_t)m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return (schar_t)m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (schar_t)(ldbl_val.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
unsigned char
|
|
|
|
Scalar::UChar(unsigned char fail_value) const
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (uchar_t)(m_integer.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
return (uchar_t)m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return (uchar_t)m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (uchar_t)(ldbl_val.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
short
|
|
|
|
Scalar::SShort(short fail_value) const
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (sshort_t)(m_integer.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
return (sshort_t)m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return (sshort_t)m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (sshort_t)(ldbl_val.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue();
|
2015-08-07 14:39:38 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
unsigned short
|
|
|
|
Scalar::UShort(unsigned short fail_value) const
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
2015-08-17 20:05:31 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (ushort_t)(m_integer.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue();
|
2015-08-17 23:28:05 +08:00
|
|
|
case e_float:
|
2015-08-20 17:12:46 +08:00
|
|
|
return (ushort_t)m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return (ushort_t)m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (ushort_t)(ldbl_val.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
2015-08-17 20:05:31 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
int
|
|
|
|
Scalar::SInt(int fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (sint_t)(m_integer.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
return (sint_t)m_float.convertToFloat();
|
2015-08-17 20:05:31 +08:00
|
|
|
case e_double:
|
2015-08-20 17:12:46 +08:00
|
|
|
return (sint_t)m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (sint_t)(ldbl_val.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int
|
|
|
|
Scalar::UInt(unsigned int fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (uint_t)(m_integer.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
return (uint_t)m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return (uint_t)m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (uint_t)(ldbl_val.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
long
|
|
|
|
Scalar::SLong(long fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (slong_t)(m_integer.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
return (slong_t)m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return (slong_t)m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (slong_t)(ldbl_val.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
2015-08-17 23:28:05 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
unsigned long
|
|
|
|
Scalar::ULong(unsigned long fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (ulong_t)(m_integer.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
return (ulong_t)m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return (ulong_t)m_float.convertToDouble();
|
2015-08-17 20:05:31 +08:00
|
|
|
case e_long_double:
|
2015-08-20 17:12:46 +08:00
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (ulong_t)(ldbl_val.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
long long
|
|
|
|
Scalar::SLongLong(long long fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (slonglong_t)(m_integer.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
return (slonglong_t)m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return (slonglong_t)m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (slonglong_t)(ldbl_val.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned long long
|
|
|
|
Scalar::ULongLong(unsigned long long fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (ulonglong_t)(m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue();
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
return (ulonglong_t)m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return (ulonglong_t)m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
return (ulonglong_t)(ldbl_val.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue();
|
2015-08-07 14:39:38 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
llvm::APInt
|
|
|
|
Scalar::SInt128(llvm::APInt& fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
|
|
|
return m_integer;
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
return m_float.bitcastToAPInt();
|
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
llvm::APInt
|
|
|
|
Scalar::UInt128(const llvm::APInt& fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return m_integer;
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
return m_float.bitcastToAPInt();
|
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::APInt
|
2016-03-10 08:14:29 +08:00
|
|
|
Scalar::SInt256(llvm::APInt& fail_value) const
|
2015-08-20 17:12:46 +08:00
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return m_integer;
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
return m_float.bitcastToAPInt();
|
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2016-03-10 08:14:29 +08:00
|
|
|
llvm::APInt
|
|
|
|
Scalar::UInt256(const llvm::APInt& fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
|
|
|
return m_integer;
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
return m_float.bitcastToAPInt();
|
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
float
|
|
|
|
Scalar::Float(float fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return m_integer.bitsToFloat();
|
|
|
|
case e_float:
|
|
|
|
return m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return (float_t)m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
|
|
|
return ldbl_val.bitsToFloat();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
double
|
|
|
|
Scalar::Double(double fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return m_integer.bitsToDouble();
|
|
|
|
case e_float:
|
|
|
|
return (double_t)m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
|
|
|
return ldbl_val.bitsToFloat();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
long double
|
|
|
|
Scalar::LongDouble(long double fail_value) const
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return (long_double_t)m_integer.bitsToDouble();
|
|
|
|
case e_float:
|
|
|
|
return (long_double_t)m_float.convertToFloat();
|
|
|
|
case e_double:
|
|
|
|
return (long_double_t)m_float.convertToDouble();
|
|
|
|
case e_long_double:
|
|
|
|
llvm::APInt ldbl_val = m_float.bitcastToAPInt();
|
|
|
|
return (long_double_t)ldbl_val.bitsToDouble();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return fail_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator+= (const Scalar& rhs)
|
|
|
|
{
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
|
|
|
if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) != Scalar::e_void)
|
|
|
|
{
|
|
|
|
switch (m_type)
|
2015-08-20 17:12:46 +08:00
|
|
|
{
|
|
|
|
case e_void: break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
m_integer = a->m_integer + b->m_integer;
|
|
|
|
break;
|
2016-03-12 08:31:13 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
m_float = a->m_float + b->m_float;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator<<= (const Scalar& rhs)
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
m_type = e_void;
|
|
|
|
break;
|
2015-08-11 05:49:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (rhs.m_type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_void:
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
m_type = e_void;
|
|
|
|
break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer << rhs.m_integer;
|
2015-08-20 17:12:46 +08:00
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Scalar::ShiftRightLogical(const Scalar& rhs)
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
m_type = e_void;
|
|
|
|
break;
|
2015-08-11 05:49:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (rhs.m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
m_type = e_void;
|
|
|
|
break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.lshr(rhs.m_integer);
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return m_type != e_void;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator>>= (const Scalar& rhs)
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_float:
|
2015-08-07 14:39:38 +08:00
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
m_type = e_void;
|
2010-06-09 00:52:24 +08:00
|
|
|
break;
|
|
|
|
|
2015-08-11 05:49:50 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2015-08-11 05:49:50 +08:00
|
|
|
switch (rhs.m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
m_type = e_void;
|
|
|
|
break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.ashr(rhs.m_integer);
|
2016-03-12 08:31:13 +08:00
|
|
|
break;
|
2015-08-11 05:49:50 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scalar&
|
|
|
|
Scalar::operator&= (const Scalar& rhs)
|
|
|
|
{
|
|
|
|
switch (m_type)
|
2015-08-20 17:12:46 +08:00
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
m_type = e_void;
|
2015-08-17 23:28:05 +08:00
|
|
|
break;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
2010-06-09 00:52:24 +08:00
|
|
|
case e_ulonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (rhs.m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
m_type = e_void;
|
|
|
|
break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2016-03-12 08:31:13 +08:00
|
|
|
m_integer &= rhs.m_integer;
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Scalar::AbsoluteValue()
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e_sint:
|
|
|
|
case e_slong:
|
|
|
|
case e_slonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
if (m_integer.isNegative())
|
|
|
|
m_integer = -m_integer;
|
2010-06-09 00:52:24 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
case e_uint:
|
|
|
|
case e_ulong:
|
|
|
|
case e_ulonglong: return true;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
m_float.clearSign();
|
|
|
|
return true;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Scalar::UnaryNegate()
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
m_integer = -m_integer; return true;
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
m_float.changeSign(); return true;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
Scalar::OnesComplement()
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
|
|
|
case e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_sint256:
|
|
|
|
case e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
m_integer = ~m_integer; return true;
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
case e_void:
|
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Scalar
|
|
|
|
lldb_private::operator+ (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
Scalar result;
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
|
|
|
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
|
|
|
|
{
|
|
|
|
switch (result.m_type)
|
|
|
|
{
|
|
|
|
case Scalar::e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_sint128:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
result.m_integer = a->m_integer + b->m_integer; break;
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
result.m_float = a->m_float + b->m_float; break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Scalar
|
|
|
|
lldb_private::operator- (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
Scalar result;
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
|
|
|
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
|
|
|
|
{
|
|
|
|
switch (result.m_type)
|
|
|
|
{
|
|
|
|
case Scalar::e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_sint128:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
result.m_integer = a->m_integer - b->m_integer; break;
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
result.m_float = a->m_float - b->m_float; break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Scalar
|
|
|
|
lldb_private::operator/ (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
Scalar result;
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
|
|
|
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
|
|
|
|
{
|
|
|
|
switch (result.m_type)
|
|
|
|
{
|
|
|
|
case Scalar::e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
if (b->m_integer != 0)
|
|
|
|
{
|
|
|
|
result.m_integer = a->m_integer.sdiv(b->m_integer);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
if (b->m_integer != 0)
|
|
|
|
{
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
result.m_integer = a->m_integer.udiv(b->m_integer);
|
2015-08-20 17:12:46 +08:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
if (b->m_float.isZero())
|
|
|
|
{
|
|
|
|
result.m_float = a->m_float / b->m_float;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// For division only, the only way it should make it here is if a promotion failed,
|
|
|
|
// or if we are trying to do a divide by zero.
|
|
|
|
result.m_type = Scalar::e_void;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Scalar
|
|
|
|
lldb_private::operator* (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
Scalar result;
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
|
|
|
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
|
|
|
|
{
|
|
|
|
switch (result.m_type)
|
|
|
|
{
|
|
|
|
case Scalar::e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_sint128:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
result.m_integer = a->m_integer * b->m_integer; break;
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
result.m_float = a->m_float * b->m_float; break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Scalar
|
|
|
|
lldb_private::operator& (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
Scalar result;
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
|
|
|
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
|
|
|
|
{
|
|
|
|
switch (result.m_type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_sint128:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
result.m_integer = a->m_integer & b->m_integer; break;
|
2010-06-09 00:52:24 +08:00
|
|
|
case Scalar::e_void:
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
// No bitwise AND on floats, doubles of long doubles
|
|
|
|
result.m_type = Scalar::e_void;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Scalar
|
|
|
|
lldb_private::operator| (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
Scalar result;
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
|
|
|
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
|
|
|
|
{
|
|
|
|
switch (result.m_type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_sint128:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
result.m_integer = a->m_integer | b->m_integer; break;
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
case Scalar::e_void:
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
// No bitwise AND on floats, doubles of long doubles
|
|
|
|
result.m_type = Scalar::e_void;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Scalar
|
|
|
|
lldb_private::operator% (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
Scalar result;
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
|
|
|
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
|
|
|
|
{
|
|
|
|
switch (result.m_type)
|
|
|
|
{
|
2013-08-09 01:57:00 +08:00
|
|
|
default: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_void: break;
|
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
if (b->m_integer != 0)
|
|
|
|
{
|
|
|
|
result.m_integer = a->m_integer.srem(b->m_integer);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
if (b->m_integer != 0)
|
|
|
|
{
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
result.m_integer = a->m_integer.urem(b->m_integer);
|
2015-08-20 17:12:46 +08:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
break;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
2013-08-09 01:57:00 +08:00
|
|
|
result.m_type = Scalar::e_void;
|
2010-06-09 00:52:24 +08:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Scalar
|
|
|
|
lldb_private::operator^ (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
Scalar result;
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
|
|
|
if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
|
|
|
|
{
|
|
|
|
switch (result.m_type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_sint128:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
result.m_integer = a->m_integer ^ b->m_integer; break;
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
case Scalar::e_void:
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
// No bitwise AND on floats, doubles of long doubles
|
|
|
|
result.m_type = Scalar::e_void;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2013-01-10 06:44:41 +08:00
|
|
|
const Scalar
|
|
|
|
lldb_private::operator<< (const Scalar& lhs, const Scalar &rhs)
|
|
|
|
{
|
|
|
|
Scalar result = lhs;
|
|
|
|
result <<= rhs;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Scalar
|
|
|
|
lldb_private::operator>> (const Scalar& lhs, const Scalar &rhs)
|
|
|
|
{
|
|
|
|
Scalar result = lhs;
|
|
|
|
result >>= rhs;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
Error
|
2013-01-26 02:06:21 +08:00
|
|
|
Scalar::SetValueFromCString (const char *value_str, Encoding encoding, size_t byte_size)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
Error error;
|
2016-03-12 08:31:13 +08:00
|
|
|
if (value_str == nullptr || value_str[0] == '\0')
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
error.SetErrorString ("Invalid c-string value string.");
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
bool success = false;
|
|
|
|
switch (encoding)
|
|
|
|
{
|
|
|
|
case eEncodingInvalid:
|
|
|
|
error.SetErrorString ("Invalid encoding.");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eEncodingUint:
|
|
|
|
if (byte_size <= sizeof (unsigned long long))
|
|
|
|
{
|
2015-01-16 04:08:35 +08:00
|
|
|
uint64_t uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success);
|
2010-06-09 00:52:24 +08:00
|
|
|
if (!success)
|
2011-10-26 08:56:27 +08:00
|
|
|
error.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string value", value_str);
|
2010-06-09 00:52:24 +08:00
|
|
|
else if (!UIntValueIsValidForSize (uval64, byte_size))
|
2014-03-03 23:39:47 +08:00
|
|
|
error.SetErrorStringWithFormat("value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value", uval64, (uint64_t)byte_size);
|
2010-06-09 00:52:24 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
m_type = Scalar::GetValueTypeForUnsignedIntegerWithByteSize (byte_size);
|
|
|
|
switch (m_type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_uint: m_integer = llvm::APInt(sizeof(uint_t) * 8, uval64, false); break;
|
|
|
|
case e_ulong: m_integer = llvm::APInt(sizeof(ulong_t) * 8, uval64, false); break;
|
|
|
|
case e_ulonglong: m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, uval64, false); break;
|
2010-06-09 00:52:24 +08:00
|
|
|
default:
|
2014-03-03 23:39:47 +08:00
|
|
|
error.SetErrorStringWithFormat("unsupported unsigned integer byte size: %" PRIu64 "", (uint64_t)byte_size);
|
2010-06-09 00:52:24 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-03-03 23:39:47 +08:00
|
|
|
error.SetErrorStringWithFormat("unsupported unsigned integer byte size: %" PRIu64 "", (uint64_t)byte_size);
|
2010-06-09 00:52:24 +08:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eEncodingSint:
|
|
|
|
if (byte_size <= sizeof (long long))
|
|
|
|
{
|
2015-01-16 04:08:35 +08:00
|
|
|
uint64_t sval64 = StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success);
|
2010-06-09 00:52:24 +08:00
|
|
|
if (!success)
|
2011-10-26 08:56:27 +08:00
|
|
|
error.SetErrorStringWithFormat ("'%s' is not a valid signed integer string value", value_str);
|
2010-06-09 00:52:24 +08:00
|
|
|
else if (!SIntValueIsValidForSize (sval64, byte_size))
|
2014-03-03 23:39:47 +08:00
|
|
|
error.SetErrorStringWithFormat("value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte signed integer value", sval64, (uint64_t)byte_size);
|
2010-06-09 00:52:24 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
m_type = Scalar::GetValueTypeForSignedIntegerWithByteSize (byte_size);
|
|
|
|
switch (m_type)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_sint: m_integer = llvm::APInt(sizeof(sint_t) * 8, sval64, true); break;
|
|
|
|
case e_slong: m_integer = llvm::APInt(sizeof(slong_t) * 8, sval64, true); break;
|
|
|
|
case e_slonglong: m_integer = llvm::APInt(sizeof(slonglong_t) * 8, sval64, true); break;
|
2010-06-09 00:52:24 +08:00
|
|
|
default:
|
2014-03-03 23:39:47 +08:00
|
|
|
error.SetErrorStringWithFormat("unsupported signed integer byte size: %" PRIu64 "", (uint64_t)byte_size);
|
2010-06-09 00:52:24 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-03-03 23:39:47 +08:00
|
|
|
error.SetErrorStringWithFormat("unsupported signed integer byte size: %" PRIu64 "", (uint64_t)byte_size);
|
2010-06-09 00:52:24 +08:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eEncodingIEEE754:
|
2015-08-20 17:12:46 +08:00
|
|
|
static float f_val;
|
|
|
|
static double d_val;
|
|
|
|
static long double l_val;
|
2010-06-09 00:52:24 +08:00
|
|
|
if (byte_size == sizeof (float))
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
if (::sscanf (value_str, "%f", &f_val) == 1)
|
|
|
|
{
|
|
|
|
m_float = llvm::APFloat(f_val);
|
2010-06-09 00:52:24 +08:00
|
|
|
m_type = e_float;
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
else
|
2011-10-26 08:56:27 +08:00
|
|
|
error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
else if (byte_size == sizeof (double))
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
if (::sscanf (value_str, "%lf", &d_val) == 1)
|
|
|
|
{
|
|
|
|
m_float = llvm::APFloat(d_val);
|
2010-06-09 00:52:24 +08:00
|
|
|
m_type = e_double;
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
else
|
2011-10-26 08:56:27 +08:00
|
|
|
error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
else if (byte_size == sizeof (long double))
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
if (::sscanf (value_str, "%Lf", &l_val) == 1)
|
|
|
|
{
|
|
|
|
m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&l_val)->x));
|
2010-06-09 00:52:24 +08:00
|
|
|
m_type = e_long_double;
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
else
|
2011-10-26 08:56:27 +08:00
|
|
|
error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-03-03 23:39:47 +08:00
|
|
|
error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "", (uint64_t)byte_size);
|
2010-06-09 00:52:24 +08:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case eEncodingVector:
|
2011-10-26 08:56:27 +08:00
|
|
|
error.SetErrorString ("vector encoding unsupported.");
|
2010-06-09 00:52:24 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (error.Fail())
|
|
|
|
m_type = e_void;
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2013-04-13 09:21:23 +08:00
|
|
|
Error
|
|
|
|
Scalar::SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t byte_size)
|
|
|
|
{
|
|
|
|
Error error;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
type128 int128;
|
2016-03-10 08:14:29 +08:00
|
|
|
type256 int256;
|
2013-04-13 09:21:23 +08:00
|
|
|
switch (encoding)
|
|
|
|
{
|
|
|
|
case lldb::eEncodingInvalid:
|
|
|
|
error.SetErrorString ("invalid encoding");
|
|
|
|
break;
|
|
|
|
case lldb::eEncodingVector:
|
|
|
|
error.SetErrorString ("vector encoding unsupported");
|
|
|
|
break;
|
|
|
|
case lldb::eEncodingUint:
|
|
|
|
{
|
2015-06-02 01:08:30 +08:00
|
|
|
lldb::offset_t offset = 0;
|
2013-04-13 09:21:23 +08:00
|
|
|
|
|
|
|
switch (byte_size)
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case 1: operator=((uint8_t)data.GetU8(&offset)); break;
|
|
|
|
case 2: operator=((uint16_t)data.GetU16(&offset)); break;
|
|
|
|
case 4: operator=((uint32_t)data.GetU32(&offset)); break;
|
|
|
|
case 8: operator=((uint64_t)data.GetU64(&offset)); break;
|
|
|
|
case 16:
|
|
|
|
if (data.GetByteOrder() == eByteOrderBig)
|
|
|
|
{
|
|
|
|
int128.x[1] = (uint64_t)data.GetU64 (&offset);
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
int128.x[0] = (uint64_t)data.GetU64 (&offset);
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int128.x[0] = (uint64_t)data.GetU64 (&offset);
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
int128.x[1] = (uint64_t)data.GetU64 (&offset);
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
|
|
|
operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
|
|
|
|
break;
|
2016-03-10 08:14:29 +08:00
|
|
|
case 32:
|
|
|
|
if (data.GetByteOrder() == eByteOrderBig)
|
|
|
|
{
|
|
|
|
int256.x[3] = (uint64_t)data.GetU64 (&offset);
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
int256.x[2] = (uint64_t)data.GetU64 (&offset);
|
|
|
|
int256.x[1] = (uint64_t)data.GetU64 (&offset);
|
|
|
|
int256.x[0] = (uint64_t)data.GetU64 (&offset);
|
2016-03-10 08:14:29 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int256.x[0] = (uint64_t)data.GetU64 (&offset);
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
int256.x[1] = (uint64_t)data.GetU64 (&offset);
|
|
|
|
int256.x[2] = (uint64_t)data.GetU64 (&offset);
|
|
|
|
int256.x[3] = (uint64_t)data.GetU64 (&offset);
|
2016-03-10 08:14:29 +08:00
|
|
|
}
|
|
|
|
operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
|
|
|
|
break;
|
2013-04-13 09:21:23 +08:00
|
|
|
default:
|
2014-03-03 23:39:47 +08:00
|
|
|
error.SetErrorStringWithFormat("unsupported unsigned integer byte size: %" PRIu64 "", (uint64_t)byte_size);
|
2013-04-13 09:21:23 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case lldb::eEncodingSint:
|
|
|
|
{
|
2015-06-02 01:08:30 +08:00
|
|
|
lldb::offset_t offset = 0;
|
2013-04-13 09:21:23 +08:00
|
|
|
|
|
|
|
switch (byte_size)
|
|
|
|
{
|
|
|
|
case 1: operator=((int8_t)data.GetU8(&offset)); break;
|
|
|
|
case 2: operator=((int16_t)data.GetU16(&offset)); break;
|
|
|
|
case 4: operator=((int32_t)data.GetU32(&offset)); break;
|
|
|
|
case 8: operator=((int64_t)data.GetU64(&offset)); break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case 16:
|
|
|
|
if (data.GetByteOrder() == eByteOrderBig)
|
|
|
|
{
|
|
|
|
int128.x[1] = (uint64_t)data.GetU64 (&offset);
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
int128.x[0] = (uint64_t)data.GetU64 (&offset);
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int128.x[0] = (uint64_t)data.GetU64 (&offset);
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
int128.x[1] = (uint64_t)data.GetU64 (&offset);
|
2015-08-20 17:12:46 +08:00
|
|
|
}
|
|
|
|
operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
|
|
|
|
break;
|
2016-03-10 08:14:29 +08:00
|
|
|
case 32:
|
|
|
|
if (data.GetByteOrder() == eByteOrderBig)
|
|
|
|
{
|
|
|
|
int256.x[3] = (uint64_t)data.GetU64 (&offset);
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
int256.x[2] = (uint64_t)data.GetU64 (&offset);
|
|
|
|
int256.x[1] = (uint64_t)data.GetU64 (&offset);
|
|
|
|
int256.x[0] = (uint64_t)data.GetU64 (&offset);
|
2016-03-10 08:14:29 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int256.x[0] = (uint64_t)data.GetU64 (&offset);
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
int256.x[1] = (uint64_t)data.GetU64 (&offset);
|
|
|
|
int256.x[2] = (uint64_t)data.GetU64 (&offset);
|
|
|
|
int256.x[3] = (uint64_t)data.GetU64 (&offset);
|
2016-03-10 08:14:29 +08:00
|
|
|
}
|
|
|
|
operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
|
|
|
|
break;
|
2013-04-13 09:21:23 +08:00
|
|
|
default:
|
2014-03-03 23:39:47 +08:00
|
|
|
error.SetErrorStringWithFormat("unsupported signed integer byte size: %" PRIu64 "", (uint64_t)byte_size);
|
2013-04-13 09:21:23 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case lldb::eEncodingIEEE754:
|
|
|
|
{
|
2015-06-02 01:08:30 +08:00
|
|
|
lldb::offset_t offset = 0;
|
2013-04-13 09:21:23 +08:00
|
|
|
|
|
|
|
if (byte_size == sizeof (float))
|
|
|
|
operator=((float)data.GetFloat(&offset));
|
|
|
|
else if (byte_size == sizeof (double))
|
|
|
|
operator=((double)data.GetDouble(&offset));
|
|
|
|
else if (byte_size == sizeof (long double))
|
|
|
|
operator=((long double)data.GetLongDouble(&offset));
|
|
|
|
else
|
2014-03-03 23:39:47 +08:00
|
|
|
error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "", (uint64_t)byte_size);
|
2013-04-13 09:21:23 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2011-05-19 08:17:26 +08:00
|
|
|
bool
|
|
|
|
Scalar::SignExtend (uint32_t sign_bit_pos)
|
|
|
|
{
|
|
|
|
const uint32_t max_bit_pos = GetByteSize() * 8;
|
|
|
|
|
|
|
|
if (sign_bit_pos < max_bit_pos)
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case Scalar::e_void:
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
return false;
|
2015-08-11 05:49:50 +08:00
|
|
|
|
2011-05-19 08:17:26 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_ulonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint128:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
|
|
|
case Scalar::e_uint256:
|
2011-05-19 08:17:26 +08:00
|
|
|
if (max_bit_pos == sign_bit_pos)
|
|
|
|
return true;
|
|
|
|
else if (sign_bit_pos < (max_bit_pos-1))
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
llvm::APInt sign_bit = llvm::APInt::getSignBit(sign_bit_pos + 1);
|
|
|
|
llvm::APInt bitwize_and = m_integer & sign_bit;
|
|
|
|
if (bitwize_and.getBoolValue())
|
2011-05-19 08:17:26 +08:00
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
const llvm::APInt mask = ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1);
|
|
|
|
m_integer |= mask;
|
2011-05-19 08:17:26 +08:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-01-26 02:06:21 +08:00
|
|
|
size_t
|
Added new lldb_private::Process memory read/write functions to stop a bunch
of duplicated code from appearing all over LLDB:
lldb::addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error);
bool
Process::WritePointerToMemory (lldb::addr_t vm_addr, lldb::addr_t ptr_value, Error &error);
size_t
Process::ReadScalarIntegerFromMemory (lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Error &error);
size_t
Process::WriteScalarToMemory (lldb::addr_t vm_addr, const Scalar &scalar, uint32_t size, Error &error);
in lldb_private::Process the following functions were renamed:
From:
uint64_t
Process::ReadUnsignedInteger (lldb::addr_t load_addr,
size_t byte_size,
Error &error);
To:
uint64_t
Process::ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
size_t byte_size,
uint64_t fail_value,
Error &error);
Cleaned up a lot of code that was manually doing what the above functions do
to use the functions listed above.
Added the ability to get a scalar value as a buffer that can be written down
to a process (byte swapping the Scalar value if needed):
uint32_t
Scalar::GetAsMemoryData (void *dst,
uint32_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
The "dst_len" can be smaller that the size of the scalar and the least
significant bytes will be written. "dst_len" can also be larger and the
most significant bytes will be padded with zeroes.
Centralized the code that adds or removes address bits for callable and opcode
addresses into lldb_private::Target:
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
All necessary lldb_private::Address functions now use the target versions so
changes should only need to happen in one place if anything needs updating.
Fixed up a lot of places that were calling :
addr_t
Address::GetLoadAddress(Target*);
to call the Address::GetCallableLoadAddress() or Address::GetOpcodeLoadAddress()
as needed. There were many places in the breakpoint code where things could
go wrong for ARM if these weren't used.
llvm-svn: 131878
2011-05-23 06:46:53 +08:00
|
|
|
Scalar::GetAsMemoryData (void *dst,
|
2013-01-26 02:06:21 +08:00
|
|
|
size_t dst_len,
|
Added new lldb_private::Process memory read/write functions to stop a bunch
of duplicated code from appearing all over LLDB:
lldb::addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error);
bool
Process::WritePointerToMemory (lldb::addr_t vm_addr, lldb::addr_t ptr_value, Error &error);
size_t
Process::ReadScalarIntegerFromMemory (lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Error &error);
size_t
Process::WriteScalarToMemory (lldb::addr_t vm_addr, const Scalar &scalar, uint32_t size, Error &error);
in lldb_private::Process the following functions were renamed:
From:
uint64_t
Process::ReadUnsignedInteger (lldb::addr_t load_addr,
size_t byte_size,
Error &error);
To:
uint64_t
Process::ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
size_t byte_size,
uint64_t fail_value,
Error &error);
Cleaned up a lot of code that was manually doing what the above functions do
to use the functions listed above.
Added the ability to get a scalar value as a buffer that can be written down
to a process (byte swapping the Scalar value if needed):
uint32_t
Scalar::GetAsMemoryData (void *dst,
uint32_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
The "dst_len" can be smaller that the size of the scalar and the least
significant bytes will be written. "dst_len" can also be larger and the
most significant bytes will be padded with zeroes.
Centralized the code that adds or removes address bits for callable and opcode
addresses into lldb_private::Target:
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
All necessary lldb_private::Address functions now use the target versions so
changes should only need to happen in one place if anything needs updating.
Fixed up a lot of places that were calling :
addr_t
Address::GetLoadAddress(Target*);
to call the Address::GetCallableLoadAddress() or Address::GetOpcodeLoadAddress()
as needed. There were many places in the breakpoint code where things could
go wrong for ARM if these weren't used.
llvm-svn: 131878
2011-05-23 06:46:53 +08:00
|
|
|
lldb::ByteOrder dst_byte_order,
|
|
|
|
Error &error) const
|
|
|
|
{
|
|
|
|
// Get a data extractor that points to the native scalar data
|
|
|
|
DataExtractor data;
|
|
|
|
if (!GetData(data))
|
|
|
|
{
|
|
|
|
error.SetErrorString ("invalid scalar value");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const size_t src_len = data.GetByteSize();
|
|
|
|
|
|
|
|
// Prepare a memory buffer that contains some or all of the register value
|
2013-01-26 02:06:21 +08:00
|
|
|
const size_t bytes_copied = data.CopyByteOrderedData (0, // src offset
|
Added new lldb_private::Process memory read/write functions to stop a bunch
of duplicated code from appearing all over LLDB:
lldb::addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error);
bool
Process::WritePointerToMemory (lldb::addr_t vm_addr, lldb::addr_t ptr_value, Error &error);
size_t
Process::ReadScalarIntegerFromMemory (lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Error &error);
size_t
Process::WriteScalarToMemory (lldb::addr_t vm_addr, const Scalar &scalar, uint32_t size, Error &error);
in lldb_private::Process the following functions were renamed:
From:
uint64_t
Process::ReadUnsignedInteger (lldb::addr_t load_addr,
size_t byte_size,
Error &error);
To:
uint64_t
Process::ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
size_t byte_size,
uint64_t fail_value,
Error &error);
Cleaned up a lot of code that was manually doing what the above functions do
to use the functions listed above.
Added the ability to get a scalar value as a buffer that can be written down
to a process (byte swapping the Scalar value if needed):
uint32_t
Scalar::GetAsMemoryData (void *dst,
uint32_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
The "dst_len" can be smaller that the size of the scalar and the least
significant bytes will be written. "dst_len" can also be larger and the
most significant bytes will be padded with zeroes.
Centralized the code that adds or removes address bits for callable and opcode
addresses into lldb_private::Target:
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
All necessary lldb_private::Address functions now use the target versions so
changes should only need to happen in one place if anything needs updating.
Fixed up a lot of places that were calling :
addr_t
Address::GetLoadAddress(Target*);
to call the Address::GetCallableLoadAddress() or Address::GetOpcodeLoadAddress()
as needed. There were many places in the breakpoint code where things could
go wrong for ARM if these weren't used.
llvm-svn: 131878
2011-05-23 06:46:53 +08:00
|
|
|
src_len, // src length
|
|
|
|
dst, // dst buffer
|
|
|
|
dst_len, // dst length
|
|
|
|
dst_byte_order); // dst byte order
|
|
|
|
if (bytes_copied == 0)
|
|
|
|
error.SetErrorString ("failed to copy data");
|
|
|
|
|
|
|
|
return bytes_copied;
|
|
|
|
}
|
|
|
|
|
2011-12-29 09:26:56 +08:00
|
|
|
bool
|
|
|
|
Scalar::ExtractBitfield (uint32_t bit_size,
|
|
|
|
uint32_t bit_offset)
|
|
|
|
{
|
|
|
|
if (bit_size == 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case Scalar::e_void:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
2011-12-29 09:26:56 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case Scalar::e_sint:
|
2015-08-17 23:28:05 +08:00
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_slonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.ashr(bit_offset).trunc(bit_size).sext(8 * GetByteSize());
|
2015-08-17 23:28:05 +08:00
|
|
|
return true;
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_ulong:
|
2011-12-29 09:26:56 +08:00
|
|
|
case Scalar::e_ulonglong:
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_uint256:
|
Fix usage of APInt.getRawData for big-endian systems
The Scalar implementation and a few other places in LLDB directly
access the internal implementation of APInt values using the
getRawData method. Unfortunately, pretty much all of these places
do not handle big-endian systems correctly. While on little-endian
machines, the pointer returned by getRawData can simply be used as
a pointer to the integer value in its natural format, no matter
what size, this is not true on big-endian systems: getRawData
actually points to an array of type uint64_t, with the first element
of the array always containing the least-significant word of the
integer. This means that if the bitsize of that integer is smaller
than 64, we need to add an offset to the pointer returned by
getRawData in order to access the value in its natural type, and
if the bitsize is *larger* than 64, we actually have to swap the
constituent words before we can access the value in its natural type.
This patch fixes every incorrect use of getRawData in the code base.
For the most part, this is done by simply removing uses of getRawData
in the first place, and using other APInt member functions to operate
on the integer data.
This can be done in many member functions of Scalar itself, as well
as in Symbol/Type.h and in IRInterpreter::Interpret. For the latter,
I've had to add a Scalar::MakeUnsigned routine to parallel the existing
Scalar::MakeSigned, e.g. in order to implement an unsigned divide.
The Scalar::RawUInt, Scalar::RawULong, and Scalar::RawULongLong
were already unused and can be simply removed. I've also removed
the Scalar::GetRawBits64 function and its few users.
The one remaining user of getRawData in Scalar.cpp is GetBytes.
I've implemented all the cases described above to correctly
implement access to the underlying integer data on big-endian
systems. GetData now simply calls GetBytes instead of reimplementing
its contents.
Finally, two places in the clang interface code were also accessing
APInt.getRawData in order to actually construct a byte representation
of an integer. I've changed those to make use of a Scalar instead,
to avoid having to re-implement the logic there.
The patch also adds a couple of unit tests verifying correct operation
of the GetBytes routine as well as the conversion routines. Those tests
actually exposed more problems in the Scalar code: the SetValueFromData
routine didn't work correctly for 128- and 256-bit data types, and the
SChar routine should have an explicit "signed char" return type to work
correctly on platforms where char defaults to unsigned.
Differential Revision: http://reviews.llvm.org/D18981
llvm-svn: 266311
2016-04-14 22:32:01 +08:00
|
|
|
m_integer = m_integer.lshr(bit_offset).trunc(bit_size).zext(8 * GetByteSize());
|
2011-12-29 09:26:56 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
bool
|
|
|
|
lldb_private::operator== (const Scalar& lhs, const 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)
|
|
|
|
return lhs.m_type == rhs.m_type;
|
|
|
|
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
2015-08-20 17:12:46 +08:00
|
|
|
llvm::APFloat::cmpResult result;
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
|
|
|
|
{
|
|
|
|
case Scalar::e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_sint128:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return a->m_integer == b->m_integer;
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
result = a->m_float.compare(b->m_float);
|
|
|
|
if(result == llvm::APFloat::cmpEqual)
|
|
|
|
return true;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
lldb_private::operator!= (const Scalar& lhs, const 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)
|
|
|
|
return lhs.m_type != rhs.m_type;
|
|
|
|
|
|
|
|
Scalar temp_value; // A temp value that might get a copy of either promoted value
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
2015-08-20 17:12:46 +08:00
|
|
|
llvm::APFloat::cmpResult result;
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
|
|
|
|
{
|
|
|
|
case Scalar::e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_sint128:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return a->m_integer != b->m_integer;
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
result = a->m_float.compare(b->m_float);
|
|
|
|
if(result != llvm::APFloat::cmpEqual)
|
|
|
|
return true;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
lldb_private::operator< (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
2015-08-20 17:12:46 +08:00
|
|
|
llvm::APFloat::cmpResult result;
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
|
|
|
|
{
|
|
|
|
case Scalar::e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return a->m_integer.slt(b->m_integer);
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return a->m_integer.ult(b->m_integer);
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
result = a->m_float.compare(b->m_float);
|
|
|
|
if(result == llvm::APFloat::cmpLessThan)
|
|
|
|
return true;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
lldb_private::operator<= (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
2015-08-20 17:12:46 +08:00
|
|
|
llvm::APFloat::cmpResult result;
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
|
|
|
|
{
|
|
|
|
case Scalar::e_void: break;
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return a->m_integer.sle(b->m_integer);
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return a->m_integer.ule(b->m_integer);
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
result = a->m_float.compare(b->m_float);
|
|
|
|
if(result == llvm::APFloat::cmpLessThan || result == llvm::APFloat::cmpEqual)
|
|
|
|
return true;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
lldb_private::operator> (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
2015-08-20 17:12:46 +08:00
|
|
|
llvm::APFloat::cmpResult result;
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_void: break;
|
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return a->m_integer.sgt(b->m_integer);
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return a->m_integer.ugt(b->m_integer);
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
result = a->m_float.compare(b->m_float);
|
|
|
|
if(result == llvm::APFloat::cmpGreaterThan)
|
|
|
|
return true;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
lldb_private::operator>= (const Scalar& lhs, const Scalar& rhs)
|
|
|
|
{
|
|
|
|
if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Scalar temp_value;
|
|
|
|
const Scalar* a;
|
|
|
|
const Scalar* b;
|
2015-08-20 17:12:46 +08:00
|
|
|
llvm::APFloat::cmpResult result;
|
2010-06-09 00:52:24 +08:00
|
|
|
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
|
|
|
|
{
|
2015-08-20 17:12:46 +08:00
|
|
|
case Scalar::e_void: break;
|
|
|
|
case Scalar::e_sint:
|
|
|
|
case Scalar::e_slong:
|
|
|
|
case Scalar::e_slonglong:
|
|
|
|
case Scalar::e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_sint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return a->m_integer.sge(b->m_integer);
|
|
|
|
case Scalar::e_uint:
|
|
|
|
case Scalar::e_ulong:
|
|
|
|
case Scalar::e_ulonglong:
|
|
|
|
case Scalar::e_uint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case Scalar::e_uint256:
|
2015-08-20 17:12:46 +08:00
|
|
|
return a->m_integer.uge(b->m_integer);
|
|
|
|
case Scalar::e_float:
|
|
|
|
case Scalar::e_double:
|
|
|
|
case Scalar::e_long_double:
|
|
|
|
result = a->m_float.compare(b->m_float);
|
|
|
|
if(result == llvm::APFloat::cmpGreaterThan || result == llvm::APFloat::cmpEqual)
|
|
|
|
return true;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
bool
|
|
|
|
Scalar::ClearBit (uint32_t bit)
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint128:
|
|
|
|
case e_sint256:
|
|
|
|
case e_uint256: m_integer.clearBit(bit); return true;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double: break;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2015-08-20 17:12:46 +08:00
|
|
|
bool
|
|
|
|
Scalar::SetBit (uint32_t bit)
|
|
|
|
{
|
|
|
|
switch (m_type)
|
|
|
|
{
|
|
|
|
case e_void:
|
|
|
|
break;
|
|
|
|
case e_sint:
|
|
|
|
case e_uint:
|
|
|
|
case e_slong:
|
|
|
|
case e_ulong:
|
|
|
|
case e_slonglong:
|
|
|
|
case e_ulonglong:
|
|
|
|
case e_sint128:
|
2016-03-10 08:14:29 +08:00
|
|
|
case e_uint128:
|
|
|
|
case e_sint256:
|
|
|
|
case e_uint256: m_integer.setBit(bit); return true;
|
2015-08-20 17:12:46 +08:00
|
|
|
case e_float:
|
|
|
|
case e_double:
|
|
|
|
case e_long_double: break;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2015-08-11 05:49:50 +08:00
|
|
|
|