mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[AIX][XCOFF] emit vector info of traceback table.
Summary: emit vector info of traceback table. Reviewers: Jason Liu,Hubert Tong Differential Revision: https://reviews.llvm.org/D93659
This commit is contained in:
parent
bc6a656349
commit
ad7e1ecf68
@ -19,6 +19,7 @@
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
class StringRef;
|
class StringRef;
|
||||||
template <unsigned> class SmallString;
|
template <unsigned> class SmallString;
|
||||||
|
template <typename T> class Expected;
|
||||||
|
|
||||||
namespace XCOFF {
|
namespace XCOFF {
|
||||||
|
|
||||||
@ -286,7 +287,14 @@ enum SymbolAuxType : uint8_t {
|
|||||||
|
|
||||||
StringRef getMappingClassString(XCOFF::StorageMappingClass SMC);
|
StringRef getMappingClassString(XCOFF::StorageMappingClass SMC);
|
||||||
StringRef getRelocationTypeString(XCOFF::RelocationType Type);
|
StringRef getRelocationTypeString(XCOFF::RelocationType Type);
|
||||||
SmallString<32> parseParmsType(uint32_t Value, unsigned ParmsNum);
|
Expected<SmallString<32>> parseParmsType(uint32_t Value, unsigned FixedParmsNum,
|
||||||
|
unsigned FloatingParmsNum);
|
||||||
|
Expected<SmallString<32>> parseParmsTypeWithVecInfo(uint32_t Value,
|
||||||
|
unsigned FixedParmsNum,
|
||||||
|
unsigned FloatingParmsNum,
|
||||||
|
unsigned VectorParmsNum);
|
||||||
|
Expected<SmallString<32>> parseVectorParmsType(uint32_t Value,
|
||||||
|
unsigned ParmsNum);
|
||||||
|
|
||||||
struct TracebackTable {
|
struct TracebackTable {
|
||||||
enum LanguageID : uint8_t {
|
enum LanguageID : uint8_t {
|
||||||
@ -381,6 +389,8 @@ struct TracebackTable {
|
|||||||
static constexpr uint32_t ParmTypeIsVectorShortBit = 0x4000'0000;
|
static constexpr uint32_t ParmTypeIsVectorShortBit = 0x4000'0000;
|
||||||
static constexpr uint32_t ParmTypeIsVectorIntBit = 0x8000'0000;
|
static constexpr uint32_t ParmTypeIsVectorIntBit = 0x8000'0000;
|
||||||
static constexpr uint32_t ParmTypeIsVectorFloatBit = 0xC000'0000;
|
static constexpr uint32_t ParmTypeIsVectorFloatBit = 0xC000'0000;
|
||||||
|
|
||||||
|
static constexpr uint8_t WidthOfParamType = 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extended Traceback table flags.
|
// Extended Traceback table flags.
|
||||||
|
@ -857,9 +857,9 @@ public:
|
|||||||
|
|
||||||
/// Return true if the specified register is modified or read in this
|
/// Return true if the specified register is modified or read in this
|
||||||
/// function. This checks that no machine operands exist for the register or
|
/// function. This checks that no machine operands exist for the register or
|
||||||
/// any of its aliases. The register is also considered used when it is set
|
/// any of its aliases. If SkipRegMaskTest is false, the register is
|
||||||
/// in the UsedPhysRegMask.
|
/// considered used when it is set in the UsedPhysRegMask.
|
||||||
bool isPhysRegUsed(MCRegister PhysReg) const;
|
bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest = false) const;
|
||||||
|
|
||||||
/// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
|
/// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
|
||||||
/// This corresponds to the bit mask attached to register mask operands.
|
/// This corresponds to the bit mask attached to register mask operands.
|
||||||
|
@ -538,20 +538,19 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class TBVectorExt {
|
class TBVectorExt {
|
||||||
friend class XCOFFTracebackTable;
|
|
||||||
|
|
||||||
uint16_t Data;
|
uint16_t Data;
|
||||||
uint32_t VecParmsInfo;
|
SmallString<32> VecParmsInfo;
|
||||||
|
|
||||||
TBVectorExt(StringRef TBvectorStrRef);
|
TBVectorExt(StringRef TBvectorStrRef, Error &Err);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static Expected<TBVectorExt> create(StringRef TBvectorStrRef);
|
||||||
uint8_t getNumberOfVRSaved() const;
|
uint8_t getNumberOfVRSaved() const;
|
||||||
bool isVRSavedOnStack() const;
|
bool isVRSavedOnStack() const;
|
||||||
bool hasVarArgs() const;
|
bool hasVarArgs() const;
|
||||||
uint8_t getNumberOfVectorParms() const;
|
uint8_t getNumberOfVectorParms() const;
|
||||||
bool hasVMXInstruction() const;
|
bool hasVMXInstruction() const;
|
||||||
SmallString<32> getVectorParmsInfoString() const;
|
SmallString<32> getVectorParmsInfo() const { return VecParmsInfo; };
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This class provides methods to extract traceback table data from a buffer.
|
/// This class provides methods to extract traceback table data from a buffer.
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "llvm/BinaryFormat/XCOFF.h"
|
#include "llvm/BinaryFormat/XCOFF.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/Errc.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@ -76,6 +78,7 @@ StringRef XCOFF::getRelocationTypeString(XCOFF::RelocationType Type) {
|
|||||||
}
|
}
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
#undef RELOC_CASE
|
||||||
|
|
||||||
#define LANG_CASE(A) \
|
#define LANG_CASE(A) \
|
||||||
case XCOFF::TracebackTable::A: \
|
case XCOFF::TracebackTable::A: \
|
||||||
@ -104,15 +107,25 @@ StringRef XCOFF::getNameForTracebackTableLanguageId(
|
|||||||
}
|
}
|
||||||
#undef LANG_CASE
|
#undef LANG_CASE
|
||||||
|
|
||||||
SmallString<32> XCOFF::parseParmsType(uint32_t Value, unsigned ParmsNum) {
|
Expected<SmallString<32>> XCOFF::parseParmsType(uint32_t Value,
|
||||||
|
unsigned FixedParmsNum,
|
||||||
|
unsigned FloatingParmsNum) {
|
||||||
SmallString<32> ParmsType;
|
SmallString<32> ParmsType;
|
||||||
for (unsigned I = 0; I < ParmsNum; ++I) {
|
int Bits = 0;
|
||||||
if (I != 0)
|
unsigned ParsedFixedNum = 0;
|
||||||
|
unsigned ParsedFloatingNum = 0;
|
||||||
|
unsigned ParsedNum = 0;
|
||||||
|
unsigned ParmsNum = FixedParmsNum + FloatingParmsNum;
|
||||||
|
|
||||||
|
while (Bits < 32 && ParsedNum < ParmsNum) {
|
||||||
|
if (++ParsedNum > 1)
|
||||||
ParmsType += ", ";
|
ParmsType += ", ";
|
||||||
if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
|
if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
|
||||||
// Fixed parameter type.
|
// Fixed parameter type.
|
||||||
ParmsType += "i";
|
ParmsType += "i";
|
||||||
|
++ParsedFixedNum;
|
||||||
Value <<= 1;
|
Value <<= 1;
|
||||||
|
++Bits;
|
||||||
} else {
|
} else {
|
||||||
if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
|
if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
|
||||||
// Float parameter type.
|
// Float parameter type.
|
||||||
@ -120,11 +133,21 @@ SmallString<32> XCOFF::parseParmsType(uint32_t Value, unsigned ParmsNum) {
|
|||||||
else
|
else
|
||||||
// Double parameter type.
|
// Double parameter type.
|
||||||
ParmsType += "d";
|
ParmsType += "d";
|
||||||
|
++ParsedFloatingNum;
|
||||||
Value <<= 2;
|
Value <<= 2;
|
||||||
|
Bits += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(Value == 0u && "ParmsType encodes more than ParmsNum parameters.");
|
|
||||||
|
// We have more parameters than the 32 Bits could encode.
|
||||||
|
if (ParsedNum < ParmsNum)
|
||||||
|
ParmsType += ", ...";
|
||||||
|
|
||||||
|
if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
|
||||||
|
ParsedFloatingNum > FloatingParmsNum)
|
||||||
|
return createStringError(errc::invalid_argument,
|
||||||
|
"ParmsType encodes can not map to ParmsNum "
|
||||||
|
"parameters in parseParmsType.");
|
||||||
return ParmsType;
|
return ParmsType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,4 +176,94 @@ SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {
|
|||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef RELOC_CASE
|
Expected<SmallString<32>>
|
||||||
|
XCOFF::parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum,
|
||||||
|
unsigned FloatingParmsNum,
|
||||||
|
unsigned VectorParmsNum) {
|
||||||
|
SmallString<32> ParmsType;
|
||||||
|
|
||||||
|
unsigned ParsedFixedNum = 0;
|
||||||
|
unsigned ParsedFloatingNum = 0;
|
||||||
|
unsigned ParsedVectorNum = 0;
|
||||||
|
unsigned ParsedNum = 0;
|
||||||
|
unsigned ParmsNum = FixedParmsNum + FloatingParmsNum + VectorParmsNum;
|
||||||
|
|
||||||
|
for (int Bits = 0; Bits < 32 && ParsedNum < ParmsNum; Bits += 2) {
|
||||||
|
if (++ParsedNum > 1)
|
||||||
|
ParmsType += ", ";
|
||||||
|
|
||||||
|
switch (Value & TracebackTable::ParmTypeMask) {
|
||||||
|
case TracebackTable::ParmTypeIsFixedBits:
|
||||||
|
ParmsType += "i";
|
||||||
|
++ParsedFixedNum;
|
||||||
|
break;
|
||||||
|
case TracebackTable::ParmTypeIsVectorBits:
|
||||||
|
ParmsType += "v";
|
||||||
|
++ParsedVectorNum;
|
||||||
|
break;
|
||||||
|
case TracebackTable::ParmTypeIsFloatingBits:
|
||||||
|
ParmsType += "f";
|
||||||
|
++ParsedFloatingNum;
|
||||||
|
break;
|
||||||
|
case TracebackTable::ParmTypeIsDoubleBits:
|
||||||
|
ParmsType += "d";
|
||||||
|
++ParsedFloatingNum;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false && "Unrecognized bits in ParmsType.");
|
||||||
|
}
|
||||||
|
Value <<= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have more parameters than the 32 Bits could encode.
|
||||||
|
if (ParsedNum < ParmsNum)
|
||||||
|
ParmsType += ", ...";
|
||||||
|
|
||||||
|
if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
|
||||||
|
ParsedFloatingNum > FloatingParmsNum || ParsedVectorNum > VectorParmsNum)
|
||||||
|
return createStringError(
|
||||||
|
errc::invalid_argument,
|
||||||
|
"ParmsType encodes can not map to ParmsNum parameters "
|
||||||
|
"in parseParmsTypeWithVecInfo.");
|
||||||
|
|
||||||
|
return ParmsType;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expected<SmallString<32>> XCOFF::parseVectorParmsType(uint32_t Value,
|
||||||
|
unsigned ParmsNum) {
|
||||||
|
SmallString<32> ParmsType;
|
||||||
|
unsigned ParsedNum = 0;
|
||||||
|
for (int Bits = 0; ParsedNum < ParmsNum && Bits < 32; Bits += 2) {
|
||||||
|
if (++ParsedNum > 1)
|
||||||
|
ParmsType += ", ";
|
||||||
|
switch (Value & TracebackTable::ParmTypeMask) {
|
||||||
|
case TracebackTable::ParmTypeIsVectorCharBit:
|
||||||
|
ParmsType += "vc";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TracebackTable::ParmTypeIsVectorShortBit:
|
||||||
|
ParmsType += "vs";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TracebackTable::ParmTypeIsVectorIntBit:
|
||||||
|
ParmsType += "vi";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TracebackTable::ParmTypeIsVectorFloatBit:
|
||||||
|
ParmsType += "vf";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value <<= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have more parameters than the 32 Bits could encode.
|
||||||
|
if (ParsedNum < ParmsNum)
|
||||||
|
ParmsType += ", ...";
|
||||||
|
|
||||||
|
if (Value != 0u)
|
||||||
|
return createStringError(errc::invalid_argument,
|
||||||
|
"ParmsType encodes more than ParmsNum parameters "
|
||||||
|
"in parseVectorParmsType.");
|
||||||
|
return ParmsType;
|
||||||
|
}
|
||||||
|
@ -582,8 +582,9 @@ bool MachineRegisterInfo::isPhysRegModified(MCRegister PhysReg,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MachineRegisterInfo::isPhysRegUsed(MCRegister PhysReg) const {
|
bool MachineRegisterInfo::isPhysRegUsed(MCRegister PhysReg,
|
||||||
if (UsedPhysRegMask.test(PhysReg))
|
bool SkipRegMaskTest) const {
|
||||||
|
if (!SkipRegMaskTest && UsedPhysRegMask.test(PhysReg))
|
||||||
return true;
|
return true;
|
||||||
const TargetRegisterInfo *TRI = getTargetRegisterInfo();
|
const TargetRegisterInfo *TRI = getTargetRegisterInfo();
|
||||||
for (MCRegAliasIterator AliasReg(PhysReg, TRI, true); AliasReg.isValid();
|
for (MCRegAliasIterator AliasReg(PhysReg, TRI, true); AliasReg.isValid();
|
||||||
|
@ -900,15 +900,34 @@ bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) {
|
|||||||
return support::endian::read32be(Bytes.data()) == 0;
|
return support::endian::read32be(Bytes.data()) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TBVectorExt::TBVectorExt(StringRef TBvectorStrRef) {
|
|
||||||
const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
|
|
||||||
Data = support::endian::read16be(Ptr);
|
|
||||||
VecParmsInfo = support::endian::read32be(Ptr + 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
|
#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
|
||||||
#define GETVALUEWITHMASKSHIFT(X, S) \
|
#define GETVALUEWITHMASKSHIFT(X, S) \
|
||||||
((Data & (TracebackTable::X)) >> (TracebackTable::S))
|
((Data & (TracebackTable::X)) >> (TracebackTable::S))
|
||||||
|
|
||||||
|
Expected<TBVectorExt> TBVectorExt::create(StringRef TBvectorStrRef) {
|
||||||
|
Error Err = Error::success();
|
||||||
|
TBVectorExt TBTVecExt(TBvectorStrRef, Err);
|
||||||
|
if (Err)
|
||||||
|
return std::move(Err);
|
||||||
|
return TBTVecExt;
|
||||||
|
}
|
||||||
|
|
||||||
|
TBVectorExt::TBVectorExt(StringRef TBvectorStrRef, Error &Err) {
|
||||||
|
const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
|
||||||
|
Data = support::endian::read16be(Ptr);
|
||||||
|
uint32_t VecParmsTypeValue = support::endian::read32be(Ptr + 2);
|
||||||
|
unsigned ParmsNum =
|
||||||
|
GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask, NumberOfVectorParmsShift);
|
||||||
|
|
||||||
|
ErrorAsOutParameter EAO(&Err);
|
||||||
|
Expected<SmallString<32>> VecParmsTypeOrError =
|
||||||
|
parseVectorParmsType(VecParmsTypeValue, ParmsNum);
|
||||||
|
if (!VecParmsTypeOrError)
|
||||||
|
Err = VecParmsTypeOrError.takeError();
|
||||||
|
else
|
||||||
|
VecParmsInfo = VecParmsTypeOrError.get();
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t TBVectorExt::getNumberOfVRSaved() const {
|
uint8_t TBVectorExt::getNumberOfVRSaved() const {
|
||||||
return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
|
return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
|
||||||
}
|
}
|
||||||
@ -920,6 +939,7 @@ bool TBVectorExt::isVRSavedOnStack() const {
|
|||||||
bool TBVectorExt::hasVarArgs() const {
|
bool TBVectorExt::hasVarArgs() const {
|
||||||
return GETVALUEWITHMASK(HasVarArgsMask);
|
return GETVALUEWITHMASK(HasVarArgsMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t TBVectorExt::getNumberOfVectorParms() const {
|
uint8_t TBVectorExt::getNumberOfVectorParms() const {
|
||||||
return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
|
return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
|
||||||
NumberOfVectorParmsShift);
|
NumberOfVectorParmsShift);
|
||||||
@ -931,72 +951,6 @@ bool TBVectorExt::hasVMXInstruction() const {
|
|||||||
#undef GETVALUEWITHMASK
|
#undef GETVALUEWITHMASK
|
||||||
#undef GETVALUEWITHMASKSHIFT
|
#undef GETVALUEWITHMASKSHIFT
|
||||||
|
|
||||||
SmallString<32> TBVectorExt::getVectorParmsInfoString() const {
|
|
||||||
SmallString<32> ParmsType;
|
|
||||||
uint32_t Value = VecParmsInfo;
|
|
||||||
for (uint8_t I = 0; I < getNumberOfVectorParms(); ++I) {
|
|
||||||
if (I != 0)
|
|
||||||
ParmsType += ", ";
|
|
||||||
switch (Value & TracebackTable::ParmTypeMask) {
|
|
||||||
case TracebackTable::ParmTypeIsVectorCharBit:
|
|
||||||
ParmsType += "vc";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TracebackTable::ParmTypeIsVectorShortBit:
|
|
||||||
ParmsType += "vs";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TracebackTable::ParmTypeIsVectorIntBit:
|
|
||||||
ParmsType += "vi";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TracebackTable::ParmTypeIsVectorFloatBit:
|
|
||||||
ParmsType += "vf";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Value <<= 2;
|
|
||||||
}
|
|
||||||
return ParmsType;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SmallString<32> parseParmsTypeWithVecInfo(uint32_t Value,
|
|
||||||
unsigned int ParmsNum) {
|
|
||||||
SmallString<32> ParmsType;
|
|
||||||
unsigned I = 0;
|
|
||||||
bool Begin = false;
|
|
||||||
while (I < ParmsNum || Value) {
|
|
||||||
if (Begin)
|
|
||||||
ParmsType += ", ";
|
|
||||||
else
|
|
||||||
Begin = true;
|
|
||||||
|
|
||||||
switch (Value & TracebackTable::ParmTypeMask) {
|
|
||||||
case TracebackTable::ParmTypeIsFixedBits:
|
|
||||||
ParmsType += "i";
|
|
||||||
++I;
|
|
||||||
break;
|
|
||||||
case TracebackTable::ParmTypeIsVectorBits:
|
|
||||||
ParmsType += "v";
|
|
||||||
break;
|
|
||||||
case TracebackTable::ParmTypeIsFloatingBits:
|
|
||||||
ParmsType += "f";
|
|
||||||
++I;
|
|
||||||
break;
|
|
||||||
case TracebackTable::ParmTypeIsDoubleBits:
|
|
||||||
ParmsType += "d";
|
|
||||||
++I;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false && "Unrecognized bits in ParmsType.");
|
|
||||||
}
|
|
||||||
Value <<= 2;
|
|
||||||
}
|
|
||||||
assert(I == ParmsNum &&
|
|
||||||
"The total parameters number of fixed-point or floating-point "
|
|
||||||
"parameters not equal to the number in the parameter type!");
|
|
||||||
return ParmsType;
|
|
||||||
}
|
|
||||||
|
|
||||||
Expected<XCOFFTracebackTable> XCOFFTracebackTable::create(const uint8_t *Ptr,
|
Expected<XCOFFTracebackTable> XCOFFTracebackTable::create(const uint8_t *Ptr,
|
||||||
uint64_t &Size) {
|
uint64_t &Size) {
|
||||||
Error Err = Error::success();
|
Error Err = Error::success();
|
||||||
@ -1017,21 +971,13 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
|
|||||||
// Skip 8 bytes of mandatory fields.
|
// Skip 8 bytes of mandatory fields.
|
||||||
DE.getU64(Cur);
|
DE.getU64(Cur);
|
||||||
|
|
||||||
// Begin to parse optional fields.
|
unsigned FixedParmsNum = getNumberOfFixedParms();
|
||||||
if (Cur) {
|
unsigned FloatingParmsNum = getNumberOfFPParms();
|
||||||
unsigned ParmNum = getNumberOfFixedParms() + getNumberOfFPParms();
|
uint32_t ParamsTypeValue = 0;
|
||||||
|
|
||||||
// As long as there are no "fixed-point" or floating-point parameters, this
|
// Begin to parse optional fields.
|
||||||
// field remains not present even when hasVectorInfo gives true and
|
if (Cur && (FixedParmsNum + FloatingParmsNum) > 0)
|
||||||
// indicates the presence of vector parameters.
|
ParamsTypeValue = DE.getU32(Cur);
|
||||||
if (ParmNum > 0) {
|
|
||||||
uint32_t ParamsTypeValue = DE.getU32(Cur);
|
|
||||||
if (Cur)
|
|
||||||
ParmsType = hasVectorInfo()
|
|
||||||
? parseParmsTypeWithVecInfo(ParamsTypeValue, ParmNum)
|
|
||||||
: parseParmsType(ParamsTypeValue, ParmNum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Cur && hasTraceBackTableOffset())
|
if (Cur && hasTraceBackTableOffset())
|
||||||
TraceBackTableOffset = DE.getU32(Cur);
|
TraceBackTableOffset = DE.getU32(Cur);
|
||||||
@ -1060,10 +1006,35 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
|
|||||||
if (Cur && isAllocaUsed())
|
if (Cur && isAllocaUsed())
|
||||||
AllocaRegister = DE.getU8(Cur);
|
AllocaRegister = DE.getU8(Cur);
|
||||||
|
|
||||||
|
unsigned VectorParmsNum = 0;
|
||||||
if (Cur && hasVectorInfo()) {
|
if (Cur && hasVectorInfo()) {
|
||||||
StringRef VectorExtRef = DE.getBytes(Cur, 6);
|
StringRef VectorExtRef = DE.getBytes(Cur, 6);
|
||||||
if (Cur)
|
if (Cur) {
|
||||||
VecExt = TBVectorExt(VectorExtRef);
|
Expected<TBVectorExt> TBVecExtOrErr = TBVectorExt::create(VectorExtRef);
|
||||||
|
if (!TBVecExtOrErr) {
|
||||||
|
Err = TBVecExtOrErr.takeError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
VecExt = TBVecExtOrErr.get();
|
||||||
|
VectorParmsNum = VecExt.getValue().getNumberOfVectorParms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// As long as there is no fixed-point or floating-point parameter, this
|
||||||
|
// field remains not present even when hasVectorInfo gives true and
|
||||||
|
// indicates the presence of vector parameters.
|
||||||
|
if (Cur && (FixedParmsNum + FloatingParmsNum) > 0) {
|
||||||
|
Expected<SmallString<32>> ParmsTypeOrError =
|
||||||
|
hasVectorInfo()
|
||||||
|
? parseParmsTypeWithVecInfo(ParamsTypeValue, FixedParmsNum,
|
||||||
|
FloatingParmsNum, VectorParmsNum)
|
||||||
|
: parseParmsType(ParamsTypeValue, FixedParmsNum, FloatingParmsNum);
|
||||||
|
|
||||||
|
if (!ParmsTypeOrError) {
|
||||||
|
Err = ParmsTypeOrError.takeError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ParmsType = ParmsTypeOrError.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Cur && hasExtensionTable())
|
if (Cur && hasExtensionTable())
|
||||||
@ -1071,6 +1042,7 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
|
|||||||
|
|
||||||
if (!Cur)
|
if (!Cur)
|
||||||
Err = Cur.takeError();
|
Err = Cur.takeError();
|
||||||
|
|
||||||
Size = Cur.tell();
|
Size = Cur.tell();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include "llvm/Support/Casting.h"
|
#include "llvm/Support/Casting.h"
|
||||||
#include "llvm/Support/CodeGen.h"
|
#include "llvm/Support/CodeGen.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/Process.h"
|
#include "llvm/Support/Process.h"
|
||||||
#include "llvm/Support/TargetRegistry.h"
|
#include "llvm/Support/TargetRegistry.h"
|
||||||
@ -1940,7 +1941,7 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
|
|||||||
|
|
||||||
// Check the function uses floating-point processor instructions or not
|
// Check the function uses floating-point processor instructions or not
|
||||||
for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) {
|
for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) {
|
||||||
if (MRI.isPhysRegUsed(Reg)) {
|
if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
|
||||||
FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask;
|
FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1980,7 +1981,8 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
|
|||||||
FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask;
|
FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask;
|
||||||
|
|
||||||
static_assert(XCOFF::AllocRegNo == 31, "Unexpected register usage!");
|
static_assert(XCOFF::AllocRegNo == 31, "Unexpected register usage!");
|
||||||
if (MRI.isPhysRegUsed(Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
|
if (MRI.isPhysRegUsed(Subtarget->isPPC64() ? PPC::X31 : PPC::R31,
|
||||||
|
/* SkipRegMaskTest */ true))
|
||||||
FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask;
|
FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask;
|
||||||
|
|
||||||
const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
|
const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
|
||||||
@ -2025,6 +2027,20 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
|
|||||||
(SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
|
(SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
|
||||||
|
|
||||||
// Set the 6th byte of mandatory field.
|
// Set the 6th byte of mandatory field.
|
||||||
|
|
||||||
|
// Check whether has Vector Instruction,We only treat instructions uses vector
|
||||||
|
// register as vector instructions.
|
||||||
|
bool HasVectorInst = false;
|
||||||
|
for (unsigned Reg = PPC::V0; Reg <= PPC::V31; ++Reg)
|
||||||
|
if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
|
||||||
|
// Has VMX instruction.
|
||||||
|
HasVectorInst = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FI->hasVectorParms() || HasVectorInst)
|
||||||
|
SecondHalfOfMandatoryField |= TracebackTable::HasVectorInfoMask;
|
||||||
|
|
||||||
bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF);
|
bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF);
|
||||||
if (ShouldEmitEHBlock)
|
if (ShouldEmitEHBlock)
|
||||||
SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask;
|
SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask;
|
||||||
@ -2053,9 +2069,9 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
|
|||||||
(SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
|
(SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
|
||||||
|
|
||||||
// Set the 7th byte of mandatory field.
|
// Set the 7th byte of mandatory field.
|
||||||
uint32_t NumberOfFixedPara = FI->getFixedParamNum();
|
uint32_t NumberOfFixedParms = FI->getFixedParmsNum();
|
||||||
SecondHalfOfMandatoryField |=
|
SecondHalfOfMandatoryField |=
|
||||||
(NumberOfFixedPara << TracebackTable::NumberOfFixedParmsShift) &
|
(NumberOfFixedParms << TracebackTable::NumberOfFixedParmsShift) &
|
||||||
TracebackTable::NumberOfFixedParmsMask;
|
TracebackTable::NumberOfFixedParmsMask;
|
||||||
GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField,
|
GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField,
|
||||||
NumberOfFixedParms);
|
NumberOfFixedParms);
|
||||||
@ -2068,9 +2084,9 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
|
|||||||
// Always set parameter on stack.
|
// Always set parameter on stack.
|
||||||
SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask;
|
SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask;
|
||||||
|
|
||||||
uint32_t NumberOfFPPara = FI->getFloatingPointParamNum();
|
uint32_t NumberOfFPParms = FI->getFloatingPointParmsNum();
|
||||||
SecondHalfOfMandatoryField |=
|
SecondHalfOfMandatoryField |=
|
||||||
(NumberOfFPPara << TracebackTable::NumberOfFloatingPointParmsShift) &
|
(NumberOfFPParms << TracebackTable::NumberOfFloatingPointParmsShift) &
|
||||||
TracebackTable::NumberOfFloatingPointParmsMask;
|
TracebackTable::NumberOfFloatingPointParmsMask;
|
||||||
|
|
||||||
GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField,
|
GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField,
|
||||||
@ -2083,18 +2099,25 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
|
|||||||
// Generate the optional fields of traceback table.
|
// Generate the optional fields of traceback table.
|
||||||
|
|
||||||
// Parameter type.
|
// Parameter type.
|
||||||
if (NumberOfFixedPara || NumberOfFPPara) {
|
if (NumberOfFixedParms || NumberOfFPParms) {
|
||||||
assert((SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) ==
|
uint32_t ParmsTypeValue = FI->getParmsType();
|
||||||
0 &&
|
|
||||||
"VectorInfo has not been implemented.");
|
|
||||||
uint32_t ParaType = FI->getParameterType();
|
|
||||||
CommentOS << "Parameter type = "
|
|
||||||
<< XCOFF::parseParmsType(ParaType,
|
|
||||||
NumberOfFixedPara + NumberOfFPPara);
|
|
||||||
EmitComment();
|
|
||||||
OutStreamer->emitIntValueInHexWithPadding(ParaType, sizeof(ParaType));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Expected<SmallString<32>> ParmsType =
|
||||||
|
FI->hasVectorParms()
|
||||||
|
? XCOFF::parseParmsTypeWithVecInfo(
|
||||||
|
ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
|
||||||
|
FI->getVectorParmsNum())
|
||||||
|
: XCOFF::parseParmsType(ParmsTypeValue, NumberOfFixedParms,
|
||||||
|
NumberOfFPParms);
|
||||||
|
|
||||||
|
assert(ParmsType && toString(ParmsType.takeError()).c_str());
|
||||||
|
if (ParmsType) {
|
||||||
|
CommentOS << "Parameter type = " << ParmsType.get();
|
||||||
|
EmitComment();
|
||||||
|
}
|
||||||
|
OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
|
||||||
|
sizeof(ParmsTypeValue));
|
||||||
|
}
|
||||||
// Traceback table offset.
|
// Traceback table offset.
|
||||||
OutStreamer->AddComment("Function size");
|
OutStreamer->AddComment("Function size");
|
||||||
if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) {
|
if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) {
|
||||||
@ -2126,6 +2149,69 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
|
|||||||
OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg));
|
OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) {
|
||||||
|
uint16_t VRData = 0;
|
||||||
|
// Calculate the number of VRs be saved.
|
||||||
|
// Vector registers 20 through 31 are marked as reserved and cannot be used
|
||||||
|
// in the default ABI.
|
||||||
|
const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
|
||||||
|
if (Subtarget.isAIXABI() && Subtarget.hasAltivec() &&
|
||||||
|
TM.getAIXExtendedAltivecABI()) {
|
||||||
|
for (unsigned Reg = PPC::V20; Reg <= PPC::V31; ++Reg)
|
||||||
|
if (MRI.isPhysRegModified(Reg)) {
|
||||||
|
// Number of VRs saved.
|
||||||
|
VRData |=
|
||||||
|
((PPC::V31 - Reg + 1) << TracebackTable::NumberOfVRSavedShift) &
|
||||||
|
TracebackTable::NumberOfVRSavedMask;
|
||||||
|
// This bit is supposed to set only when the special register
|
||||||
|
// VRSAVE is saved on stack.
|
||||||
|
// However, IBM XL compiler sets the bit when any vector registers
|
||||||
|
// are saved on the stack. We will follow XL's behavior on AIX
|
||||||
|
// so that we don't get surprise behavior change for C code.
|
||||||
|
VRData |= TracebackTable::IsVRSavedOnStackMask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set has_varargs.
|
||||||
|
if (FI->getVarArgsFrameIndex())
|
||||||
|
VRData |= TracebackTable::HasVarArgsMask;
|
||||||
|
|
||||||
|
// Vector parameters number.
|
||||||
|
unsigned VectorParmsNum = FI->getVectorParmsNum();
|
||||||
|
VRData |= (VectorParmsNum << TracebackTable::NumberOfVectorParmsShift) &
|
||||||
|
TracebackTable::NumberOfVectorParmsMask;
|
||||||
|
|
||||||
|
if (HasVectorInst)
|
||||||
|
VRData |= TracebackTable::HasVMXInstructionMask;
|
||||||
|
|
||||||
|
GENVALUECOMMENT("NumOfVRsSaved", VRData, NumberOfVRSaved);
|
||||||
|
GENBOOLCOMMENT(", ", VRData, IsVRSavedOnStack);
|
||||||
|
GENBOOLCOMMENT(", ", VRData, HasVarArgs);
|
||||||
|
EmitComment();
|
||||||
|
OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
|
||||||
|
|
||||||
|
GENVALUECOMMENT("NumOfVectorParams", VRData, NumberOfVectorParms);
|
||||||
|
GENBOOLCOMMENT(", ", VRData, HasVMXInstruction);
|
||||||
|
EmitComment();
|
||||||
|
OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
|
||||||
|
|
||||||
|
uint32_t VecParmTypeValue = FI->getVecExtParmsType();
|
||||||
|
|
||||||
|
Expected<SmallString<32>> VecParmsType =
|
||||||
|
XCOFF::parseVectorParmsType(VecParmTypeValue, VectorParmsNum);
|
||||||
|
assert(VecParmsType && toString(VecParmsType.takeError()).c_str());
|
||||||
|
if (VecParmsType) {
|
||||||
|
CommentOS << "Vector Parameter type = " << VecParmsType.get();
|
||||||
|
EmitComment();
|
||||||
|
}
|
||||||
|
OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
|
||||||
|
sizeof(VecParmTypeValue));
|
||||||
|
// Padding 2 bytes.
|
||||||
|
CommentOS << "Padding";
|
||||||
|
EmitCommentAndValue(0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t ExtensionTableFlag = 0;
|
uint8_t ExtensionTableFlag = 0;
|
||||||
if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) {
|
if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) {
|
||||||
if (ShouldEmitEHBlock)
|
if (ShouldEmitEHBlock)
|
||||||
@ -2156,7 +2242,6 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
|
|||||||
OutStreamer->AddComment("EHInfo Table");
|
OutStreamer->AddComment("EHInfo Table");
|
||||||
OutStreamer->emitValue(Exp, DL.getPointerSize());
|
OutStreamer->emitValue(Exp, DL.getPointerSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef GENBOOLCOMMENT
|
#undef GENBOOLCOMMENT
|
||||||
#undef GENVALUECOMMENT
|
#undef GENVALUECOMMENT
|
||||||
}
|
}
|
||||||
|
@ -6954,10 +6954,38 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
|
|||||||
if (VA.isRegLoc()) {
|
if (VA.isRegLoc()) {
|
||||||
if (VA.getValVT().isScalarInteger())
|
if (VA.getValVT().isScalarInteger())
|
||||||
FuncInfo->appendParameterType(PPCFunctionInfo::FixedType);
|
FuncInfo->appendParameterType(PPCFunctionInfo::FixedType);
|
||||||
else if (VA.getValVT().isFloatingPoint() && !VA.getValVT().isVector())
|
else if (VA.getValVT().isFloatingPoint() && !VA.getValVT().isVector()) {
|
||||||
FuncInfo->appendParameterType(VA.getValVT().SimpleTy == MVT::f32
|
switch (VA.getValVT().SimpleTy) {
|
||||||
? PPCFunctionInfo::ShortFloatPoint
|
default:
|
||||||
: PPCFunctionInfo::LongFloatPoint);
|
report_fatal_error("Unhandled value type for argument.");
|
||||||
|
case MVT::f32:
|
||||||
|
FuncInfo->appendParameterType(PPCFunctionInfo::ShortFloatingPoint);
|
||||||
|
break;
|
||||||
|
case MVT::f64:
|
||||||
|
FuncInfo->appendParameterType(PPCFunctionInfo::LongFloatingPoint);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (VA.getValVT().isVector()) {
|
||||||
|
switch (VA.getValVT().SimpleTy) {
|
||||||
|
default:
|
||||||
|
report_fatal_error("Unhandled value type for argument.");
|
||||||
|
case MVT::v16i8:
|
||||||
|
FuncInfo->appendParameterType(PPCFunctionInfo::VectorChar);
|
||||||
|
break;
|
||||||
|
case MVT::v8i16:
|
||||||
|
FuncInfo->appendParameterType(PPCFunctionInfo::VectorShort);
|
||||||
|
break;
|
||||||
|
case MVT::v4i32:
|
||||||
|
case MVT::v2i64:
|
||||||
|
case MVT::v1i128:
|
||||||
|
FuncInfo->appendParameterType(PPCFunctionInfo::VectorInt);
|
||||||
|
break;
|
||||||
|
case MVT::v4f32:
|
||||||
|
case MVT::v2f64:
|
||||||
|
FuncInfo->appendParameterType(PPCFunctionInfo::VectorFloat);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Flags.isByVal() && VA.isMemLoc()) {
|
if (Flags.isByVal() && VA.isMemLoc()) {
|
||||||
|
@ -66,34 +66,122 @@ bool PPCFunctionInfo::isLiveInZExt(Register VReg) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPCFunctionInfo::appendParameterType(ParamType Type) {
|
void PPCFunctionInfo::appendParameterType(ParamType Type) {
|
||||||
uint32_t CopyParamType = ParameterType;
|
|
||||||
int Bits = 0;
|
|
||||||
|
|
||||||
// If it is fixed type, we only need to increase the FixedParamNum, for
|
ParamtersType.push_back(Type);
|
||||||
// the bit encode of fixed type is bit of zero, we do not need to change the
|
switch (Type) {
|
||||||
// ParamType.
|
case FixedType:
|
||||||
if (Type == FixedType) {
|
++FixedParmsNum;
|
||||||
++FixedParamNum;
|
return;
|
||||||
|
case ShortFloatingPoint:
|
||||||
|
case LongFloatingPoint:
|
||||||
|
++FloatingParmsNum;
|
||||||
|
return;
|
||||||
|
case VectorChar:
|
||||||
|
case VectorShort:
|
||||||
|
case VectorInt:
|
||||||
|
case VectorFloat:
|
||||||
|
++VectorParmsNum;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
llvm_unreachable("Error ParamType type.");
|
||||||
|
}
|
||||||
|
|
||||||
++FloatingPointParamNum;
|
uint32_t PPCFunctionInfo::getVecExtParmsType() const {
|
||||||
|
|
||||||
for (int I = 0;
|
uint32_t VectExtParamInfo = 0;
|
||||||
I < static_cast<int>(FloatingPointParamNum + FixedParamNum - 1); ++I) {
|
unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType;
|
||||||
if (CopyParamType & XCOFF::TracebackTable::ParmTypeIsFloatingBit) {
|
int Bits = 0;
|
||||||
// '10'b => floating point short parameter.
|
|
||||||
// '11'b => floating point long parameter.
|
if (!hasVectorParms())
|
||||||
CopyParamType <<= 2;
|
return 0;
|
||||||
Bits += 2;
|
|
||||||
|
for (const auto &Elt : ParamtersType) {
|
||||||
|
switch (Elt) {
|
||||||
|
case VectorChar:
|
||||||
|
VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
VectExtParamInfo |=
|
||||||
|
XCOFF::TracebackTable::ParmTypeIsVectorCharBit >> ShiftBits;
|
||||||
|
Bits += XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
break;
|
||||||
|
case VectorShort:
|
||||||
|
VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
VectExtParamInfo |=
|
||||||
|
XCOFF::TracebackTable::ParmTypeIsVectorShortBit >> ShiftBits;
|
||||||
|
Bits += XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
break;
|
||||||
|
case VectorInt:
|
||||||
|
VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
VectExtParamInfo |=
|
||||||
|
XCOFF::TracebackTable::ParmTypeIsVectorIntBit >> ShiftBits;
|
||||||
|
Bits += XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
break;
|
||||||
|
case VectorFloat:
|
||||||
|
VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
VectExtParamInfo |=
|
||||||
|
XCOFF::TracebackTable::ParmTypeIsVectorFloatBit >> ShiftBits;
|
||||||
|
Bits += XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There are only 32bits in the VectExtParamInfo.
|
||||||
|
if (Bits >= 32)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return Bits < 32 ? VectExtParamInfo << (32 - Bits) : VectExtParamInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PPCFunctionInfo::getParmsType() const {
|
||||||
|
uint32_t ParamsTypeInfo = 0;
|
||||||
|
unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
|
||||||
|
int Bits = 0;
|
||||||
|
for (const auto &Elt : ParamtersType) {
|
||||||
|
|
||||||
|
if (Bits > 31 || (Bits > 30 && (Elt != FixedType || hasVectorParms())))
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (Elt) {
|
||||||
|
case FixedType:
|
||||||
|
if (hasVectorParms()) {
|
||||||
|
//'00' ==> fixed parameter if HasVectorParms is true.
|
||||||
|
ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
ParamsTypeInfo |=
|
||||||
|
XCOFF::TracebackTable::ParmTypeIsFixedBits >> ShiftBits;
|
||||||
|
Bits += XCOFF::TracebackTable::WidthOfParamType;
|
||||||
} else {
|
} else {
|
||||||
// '0'b => fixed parameter.
|
//'0' ==> fixed parameter if HasVectorParms is false.
|
||||||
CopyParamType <<= 1;
|
ParamsTypeInfo <<= 1;
|
||||||
++Bits;
|
++Bits;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case ShortFloatingPoint:
|
||||||
|
// '10'b => floating point short parameter.
|
||||||
|
ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
ParamsTypeInfo |=
|
||||||
|
XCOFF::TracebackTable::ParmTypeIsFloatingBits >> ShiftBits;
|
||||||
|
Bits += XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
break;
|
||||||
|
case LongFloatingPoint:
|
||||||
|
// '11'b => floating point long parameter.
|
||||||
|
ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
ParamsTypeInfo |=
|
||||||
|
XCOFF::TracebackTable::ParmTypeIsDoubleBits >> ShiftBits;
|
||||||
|
Bits += XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
break;
|
||||||
|
case VectorChar:
|
||||||
|
case VectorShort:
|
||||||
|
case VectorInt:
|
||||||
|
case VectorFloat:
|
||||||
|
// '01' ==> vector parameter
|
||||||
|
ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
ParamsTypeInfo |=
|
||||||
|
XCOFF::TracebackTable::ParmTypeIsVectorBits >> ShiftBits;
|
||||||
|
Bits += XCOFF::TracebackTable::WidthOfParamType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(Type != FixedType && "FixedType should already be handled.");
|
return Bits < 32 ? ParamsTypeInfo << (32 - Bits) : ParamsTypeInfo;
|
||||||
if (Bits < 31)
|
|
||||||
ParameterType |= Type << (30 - Bits);
|
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,14 @@ namespace llvm {
|
|||||||
/// PowerPC target-specific information for each MachineFunction.
|
/// PowerPC target-specific information for each MachineFunction.
|
||||||
class PPCFunctionInfo : public MachineFunctionInfo {
|
class PPCFunctionInfo : public MachineFunctionInfo {
|
||||||
public:
|
public:
|
||||||
// The value in the ParamType are used to indicate the bitstrings used in the
|
|
||||||
// encoding format.
|
|
||||||
enum ParamType {
|
enum ParamType {
|
||||||
FixedType = 0x0,
|
FixedType,
|
||||||
ShortFloatPoint = 0x2,
|
ShortFloatingPoint,
|
||||||
LongFloatPoint = 0x3
|
LongFloatingPoint,
|
||||||
|
VectorChar,
|
||||||
|
VectorShort,
|
||||||
|
VectorInt,
|
||||||
|
VectorFloat
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -120,19 +122,18 @@ private:
|
|||||||
/// register for parameter passing.
|
/// register for parameter passing.
|
||||||
unsigned VarArgsNumFPR = 0;
|
unsigned VarArgsNumFPR = 0;
|
||||||
|
|
||||||
/// FixedParamNum - Number of fixed parameter.
|
/// FixedParmsNum - The number of fixed parameters.
|
||||||
unsigned FixedParamNum = 0;
|
unsigned FixedParmsNum = 0;
|
||||||
|
|
||||||
/// FloatingParamNum - Number of floating point parameter.
|
/// FloatingParmsNum - The number of floating parameters.
|
||||||
unsigned FloatingPointParamNum = 0;
|
unsigned FloatingParmsNum = 0;
|
||||||
|
|
||||||
/// ParamType - Encode type for every parameter
|
/// VectorParmsNum - The number of vector parameters.
|
||||||
/// in the order of parameters passing in.
|
unsigned VectorParmsNum = 0;
|
||||||
/// Bitstring starts from the most significant (leftmost) bit.
|
|
||||||
/// '0'b => fixed parameter.
|
/// ParamtersType - Store all the parameter's type that are saved on
|
||||||
/// '10'b => floating point short parameter.
|
/// registers.
|
||||||
/// '11'b => floating point long parameter.
|
SmallVector<ParamType, 32> ParamtersType;
|
||||||
uint32_t ParameterType = 0;
|
|
||||||
|
|
||||||
/// CRSpillFrameIndex - FrameIndex for CR spill slot for 32-bit SVR4.
|
/// CRSpillFrameIndex - FrameIndex for CR spill slot for 32-bit SVR4.
|
||||||
int CRSpillFrameIndex = 0;
|
int CRSpillFrameIndex = 0;
|
||||||
@ -224,11 +225,15 @@ public:
|
|||||||
unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; }
|
unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; }
|
||||||
void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; }
|
void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; }
|
||||||
|
|
||||||
unsigned getFixedParamNum() const { return FixedParamNum; }
|
unsigned getFixedParmsNum() const { return FixedParmsNum; }
|
||||||
|
unsigned getFloatingPointParmsNum() const { return FloatingParmsNum; }
|
||||||
|
unsigned getVectorParmsNum() const { return VectorParmsNum; }
|
||||||
|
bool hasVectorParms() const { return VectorParmsNum != 0; }
|
||||||
|
|
||||||
unsigned getFloatingPointParamNum() const { return FloatingPointParamNum; }
|
uint32_t getParmsType() const;
|
||||||
|
|
||||||
|
uint32_t getVecExtParmsType() const;
|
||||||
|
|
||||||
uint32_t getParameterType() const { return ParameterType; }
|
|
||||||
void appendParameterType(ParamType Type);
|
void appendParameterType(ParamType Type);
|
||||||
|
|
||||||
unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; }
|
unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; }
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \
|
; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \
|
||||||
; RUN: -mattr=-altivec -xcoff-traceback-table=true < %s | \
|
; RUN: -mattr=+altivec -vec-extabi -xcoff-traceback-table=true < %s | \
|
||||||
; RUN: FileCheck --check-prefixes=CHECK-ASM,COMMON %s
|
; RUN: FileCheck --check-prefixes=CHECK-ASM,COMMON %s
|
||||||
|
|
||||||
; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -function-sections \
|
; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -function-sections \
|
||||||
; RUN: -mcpu=pwr4 -mattr=-altivec < %s | \
|
; RUN: -mcpu=pwr4 -mattr=+altivec -vec-extabi < %s | \
|
||||||
; RUN: FileCheck --check-prefixes=CHECK-FUNC,COMMON %s
|
; RUN: FileCheck --check-prefixes=CHECK-FUNC,COMMON %s
|
||||||
|
|
||||||
define float @bar() #0 {
|
define float @bar() #0 {
|
||||||
@ -26,6 +26,16 @@ entry:
|
|||||||
ret float %add
|
ret float %add
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define <4 x i32> @foov() #0 {
|
||||||
|
entry:
|
||||||
|
%taken = alloca <4 x i32>, align 16
|
||||||
|
%data = alloca <4 x i32>, align 16
|
||||||
|
store <4 x i32> <i32 123, i32 0, i32 0, i32 0>, <4 x i32>* %data, align 16
|
||||||
|
call void asm sideeffect "", "~{v31},~{v30},~{v29},~{v28}"()
|
||||||
|
%0 = load <4 x i32>, <4 x i32>* %taken, align 16
|
||||||
|
ret <4 x i32> %0
|
||||||
|
}
|
||||||
|
|
||||||
; COMMON: .vbyte 4, 0x00000000 # Traceback table begin
|
; COMMON: .vbyte 4, 0x00000000 # Traceback table begin
|
||||||
; COMMON-NEXT: .byte 0x00 # Version = 0
|
; COMMON-NEXT: .byte 0x00 # Version = 0
|
||||||
; COMMON-NEXT: .byte 0x09 # Language = CPlusPlus
|
; COMMON-NEXT: .byte 0x09 # Language = CPlusPlus
|
||||||
@ -46,3 +56,28 @@ entry:
|
|||||||
; COMMON-NEXT: .byte "bar" # Function Name
|
; COMMON-NEXT: .byte "bar" # Function Name
|
||||||
; COMMON-NEXT: .byte 0x1f # AllocaUsed
|
; COMMON-NEXT: .byte 0x1f # AllocaUsed
|
||||||
; COMMON-NEXT: # -- End function
|
; COMMON-NEXT: # -- End function
|
||||||
|
|
||||||
|
; COMMON: L..foov0:
|
||||||
|
; COMMON-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
|
||||||
|
; COMMON-NEXT: .byte 0x00 # Version = 0
|
||||||
|
; COMMON-NEXT: .byte 0x09 # Language = CPlusPlus
|
||||||
|
; COMMON-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
|
||||||
|
; COMMON-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
|
||||||
|
; COMMON-NEXT: # -HasControlledStorage, -IsTOCless
|
||||||
|
; COMMON-NEXT: # -IsFloatingPointPresent
|
||||||
|
; COMMON-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
|
||||||
|
; COMMON-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
|
||||||
|
; COMMON-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
|
||||||
|
; COMMON-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
|
||||||
|
; COMMON-NEXT: .byte 0x80 # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
|
||||||
|
; COMMON-NEXT: .byte 0x00 # NumberOfFixedParms = 0
|
||||||
|
; COMMON-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
|
||||||
|
; CHECK-ASM-NEXT: .vbyte 4, L..foov0-.foov # Function size
|
||||||
|
; CHECK-FUNC-NEXT: .vbyte 4, L..foov0-.foov[PR] # Function size
|
||||||
|
; COMMON-NEXT: .vbyte 2, 0x0004 # Function name len = 4
|
||||||
|
; COMMON-NEXT: .byte "foov" # Function Name
|
||||||
|
; COMMON-NEXT: .byte 0x12 # NumOfVRsSaved = 4, +IsVRSavedOnStack, -HasVarArgs
|
||||||
|
; COMMON-NEXT: .byte 0x01 # NumOfVectorParams = 0, +HasVMXInstruction
|
||||||
|
; COMMON-NEXT: .vbyte 4, 0x00000000 # Vector Parameter type =
|
||||||
|
; COMMON-NEXT: .vbyte 2, 0x0000 # Padding
|
||||||
|
; COMMON-NEXT: # -- End function
|
||||||
|
129
test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo.ll
Normal file
129
test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo.ll
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr7 \
|
||||||
|
; RUN: -mattr=+altivec -vec-extabi -xcoff-traceback-table=true < %s | \
|
||||||
|
; RUN: FileCheck --check-prefixes=CHECK-ASM,COMMON %s
|
||||||
|
|
||||||
|
; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -function-sections \
|
||||||
|
; RUN: -mcpu=pwr7 -mattr=+altivec -vec-extabi < %s | \
|
||||||
|
; RUN: FileCheck --check-prefixes=CHECK-FUNC,COMMON %s
|
||||||
|
|
||||||
|
;; #include <altivec.h>
|
||||||
|
;; vector float f(vector int vi1, int i1, int i2, float f1, vector float vf,double d1, vector char vc1) {
|
||||||
|
;; return vec_abs(vf);
|
||||||
|
;; }
|
||||||
|
;; vector float fin(int x) {
|
||||||
|
;; vector float vf ={1.0,1.0,1.0,1.0};
|
||||||
|
;; if (x) return vf;
|
||||||
|
;; return vec_abs(vf);
|
||||||
|
;; }
|
||||||
|
|
||||||
|
define dso_local <4 x float> @f(<4 x i32> %vi1, i32 signext %i1, i32 signext %i2, float %f1, <4 x float> %vf, double %d1, <16 x i8> %vc1) #0 {
|
||||||
|
entry:
|
||||||
|
%__a.addr.i = alloca <4 x float>, align 16
|
||||||
|
%vi1.addr = alloca <4 x i32>, align 16
|
||||||
|
%i1.addr = alloca i32, align 4
|
||||||
|
%i2.addr = alloca i32, align 4
|
||||||
|
%f1.addr = alloca float, align 4
|
||||||
|
%vf.addr = alloca <4 x float>, align 16
|
||||||
|
%d1.addr = alloca double, align 8
|
||||||
|
%vc1.addr = alloca <16 x i8>, align 16
|
||||||
|
store <4 x i32> %vi1, <4 x i32>* %vi1.addr, align 16
|
||||||
|
store i32 %i1, i32* %i1.addr, align 4
|
||||||
|
store i32 %i2, i32* %i2.addr, align 4
|
||||||
|
store float %f1, float* %f1.addr, align 4
|
||||||
|
store <4 x float> %vf, <4 x float>* %vf.addr, align 16
|
||||||
|
store double %d1, double* %d1.addr, align 8
|
||||||
|
store <16 x i8> %vc1, <16 x i8>* %vc1.addr, align 16
|
||||||
|
%0 = load <4 x float>, <4 x float>* %vf.addr, align 16
|
||||||
|
store <4 x float> %0, <4 x float>* %__a.addr.i, align 16
|
||||||
|
%1 = load <4 x float>, <4 x float>* %__a.addr.i, align 16
|
||||||
|
%2 = load <4 x float>, <4 x float>* %__a.addr.i, align 16
|
||||||
|
%3 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %2) #2
|
||||||
|
ret <4 x float> %3
|
||||||
|
}
|
||||||
|
|
||||||
|
define <4 x float> @fin(i32 %x) #0 {
|
||||||
|
entry:
|
||||||
|
%__a.addr.i = alloca <4 x float>, align 16
|
||||||
|
%__res.i = alloca <4 x i32>, align 16
|
||||||
|
%retval = alloca <4 x float>, align 16
|
||||||
|
%x.addr = alloca i32, align 4
|
||||||
|
%vf = alloca <4 x float>, align 16
|
||||||
|
store i32 %x, i32* %x.addr, align 4
|
||||||
|
store <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, <4 x float>* %vf, align 16
|
||||||
|
%0 = load i32, i32* %x.addr, align 4
|
||||||
|
%tobool = icmp ne i32 %0, 0
|
||||||
|
br i1 %tobool, label %if.then, label %if.end
|
||||||
|
|
||||||
|
if.then: ; preds = %entry
|
||||||
|
%1 = load <4 x float>, <4 x float>* %vf, align 16
|
||||||
|
store <4 x float> %1, <4 x float>* %retval, align 16
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
if.end: ; preds = %entry
|
||||||
|
%2 = load <4 x float>, <4 x float>* %vf, align 16
|
||||||
|
store <4 x float> %2, <4 x float>* %__a.addr.i, align 16
|
||||||
|
%3 = load <4 x float>, <4 x float>* %__a.addr.i, align 16
|
||||||
|
%4 = bitcast <4 x float> %3 to <4 x i32>
|
||||||
|
%and.i = and <4 x i32> %4, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
|
||||||
|
store <4 x i32> %and.i, <4 x i32>* %__res.i, align 16
|
||||||
|
%5 = load <4 x i32>, <4 x i32>* %__res.i, align 16
|
||||||
|
%6 = bitcast <4 x i32> %5 to <4 x float>
|
||||||
|
store <4 x float> %6, <4 x float>* %retval, align 16
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
return: ; preds = %if.end, %if.then
|
||||||
|
%7 = load <4 x float>, <4 x float>* %retval, align 16
|
||||||
|
ret <4 x float> %7
|
||||||
|
}
|
||||||
|
|
||||||
|
declare <4 x float> @llvm.fabs.v4f32(<4 x float>) #1
|
||||||
|
|
||||||
|
; COMMON: L..f0:
|
||||||
|
; COMMON-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
|
||||||
|
; COMMON-NEXT: .byte 0x00 # Version = 0
|
||||||
|
; COMMON-NEXT: .byte 0x09 # Language = CPlusPlus
|
||||||
|
; COMMON-NEXT: .byte 0x22 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
|
||||||
|
; COMMON-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
|
||||||
|
; COMMON-NEXT: # -HasControlledStorage, -IsTOCless
|
||||||
|
; COMMON-NEXT: # +IsFloatingPointPresent
|
||||||
|
; COMMON-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
|
||||||
|
; COMMON-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
|
||||||
|
; COMMON-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
|
||||||
|
; COMMON-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
|
||||||
|
; COMMON-NEXT: .byte 0x80 # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
|
||||||
|
; COMMON-NEXT: .byte 0x02 # NumberOfFixedParms = 2
|
||||||
|
; COMMON-NEXT: .byte 0x05 # NumberOfFPParms = 2, +HasParmsOnStack
|
||||||
|
; COMMON-NEXT: .vbyte 4, 0x42740000 # Parameter type = v, i, i, f, v, d, v
|
||||||
|
; CHECK-ASM-NEXT: .vbyte 4, L..f0-.f # Function size
|
||||||
|
; CHECK-FUNC-NEXT: .vbyte 4, L..f0-.f[PR] # Function size
|
||||||
|
; COMMON-NEXT: .vbyte 2, 0x0001 # Function name len = 1
|
||||||
|
; COMMON-NEXT: .byte 102 # Function Name
|
||||||
|
; COMMON-NEXT: .byte 0x00 # NumOfVRsSaved = 0, -IsVRSavedOnStack, -HasVarArgs
|
||||||
|
; COMMON-NEXT: .byte 0x07 # NumOfVectorParams = 3, +HasVMXInstruction
|
||||||
|
; COMMON-NEXT: .vbyte 4, 0xb0000000 # Vector Parameter type = vi, vf, vc
|
||||||
|
; COMMON-NEXT: .vbyte 2, 0x0000 # Padding
|
||||||
|
|
||||||
|
; COMMON: L..fin0:
|
||||||
|
; COMMON-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
|
||||||
|
; COMMON-NEXT: .byte 0x00 # Version = 0
|
||||||
|
; COMMON-NEXT: .byte 0x09 # Language = CPlusPlus
|
||||||
|
; COMMON-NEXT: .byte 0x22 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
|
||||||
|
; COMMON-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
|
||||||
|
; COMMON-NEXT: # -HasControlledStorage, -IsTOCless
|
||||||
|
; COMMON-NEXT: # +IsFloatingPointPresent
|
||||||
|
; COMMON-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
|
||||||
|
; COMMON-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
|
||||||
|
; COMMON-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
|
||||||
|
; COMMON-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
|
||||||
|
; COMMON-NEXT: .byte 0x80 # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
|
||||||
|
; COMMON-NEXT: .byte 0x01 # NumberOfFixedParms = 1
|
||||||
|
; COMMON-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
|
||||||
|
; COMMON-NEXT: .vbyte 4, 0x00000000 # Parameter type = i
|
||||||
|
; CHECK-ASM-NEXT: .vbyte 4, L..fin0-.fin # Function size
|
||||||
|
; CHECK-FUNC-NEXT: .vbyte 4, L..fin0-.fin[PR] # Function size
|
||||||
|
; COMMON-NEXT: .vbyte 2, 0x0003 # Function name len = 3
|
||||||
|
; COMMON-NEXT: .byte "fin" # Function Name
|
||||||
|
; COMMON-NEXT: .byte 0x00 # NumOfVRsSaved = 0, -IsVRSavedOnStack, -HasVarArgs
|
||||||
|
; COMMON-NEXT: .byte 0x01 # NumOfVectorParams = 0, +HasVMXInstruction
|
||||||
|
; COMMON-NEXT: .vbyte 4, 0x00000000 # Vector Parameter type =
|
||||||
|
; COMMON-NEXT: .vbyte 2, 0x0000 # Padding
|
@ -0,0 +1,36 @@
|
|||||||
|
; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr7 \
|
||||||
|
; RUN: -mattr=+altivec -vec-extabi -xcoff-traceback-table=true 2>&1 < %s | \
|
||||||
|
; RUN: FileCheck --check-prefixes=CHECK-ASM %s
|
||||||
|
|
||||||
|
;; void f(vector float vf, ...) {
|
||||||
|
;;}
|
||||||
|
|
||||||
|
define void @f(<4 x float> %vf, ...) #0 {
|
||||||
|
entry:
|
||||||
|
%vf.addr = alloca <4 x float>, align 16
|
||||||
|
store <4 x float> %vf, <4 x float>* %vf.addr, align 16
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
;CHECK-ASM: .vbyte 4, 0x00000000 # Traceback table begin
|
||||||
|
;CHECK-ASM-NEXT: .byte 0x00 # Version = 0
|
||||||
|
;CHECK-ASM-NEXT: .byte 0x09 # Language = CPlusPlus
|
||||||
|
;CHECK-ASM-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
|
||||||
|
;CHECK-ASM-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
|
||||||
|
;CHECK-ASM-NEXT: # -HasControlledStorage, -IsTOCless
|
||||||
|
;CHECK-ASM-NEXT: # -IsFloatingPointPresent
|
||||||
|
;CHECK-ASM-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
|
||||||
|
;CHECK-ASM-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
|
||||||
|
;CHECK-ASM-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
|
||||||
|
;CHECK-ASM-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
|
||||||
|
;CHECK-ASM-NEXT: .byte 0x80 # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
|
||||||
|
;CHECK-ASM-NEXT: .byte 0x00 # NumberOfFixedParms = 0
|
||||||
|
;CHECK-ASM-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
|
||||||
|
;CHECK-ASM-NEXT: .vbyte 4, L..f0-.f # Function size
|
||||||
|
;CHECK-ASM-NEXT: .vbyte 2, 0x0001 # Function name len = 1
|
||||||
|
;CHECK-ASM-NEXT: .byte 102 # Function Name
|
||||||
|
;CHECK-ASM-NEXT: .byte 0x01 # NumOfVRsSaved = 0, -IsVRSavedOnStack, +HasVarArgs
|
||||||
|
;CHECK-ASM-NEXT: .byte 0x03 # NumOfVectorParams = 1, +HasVMXInstruction
|
||||||
|
;CHECK-ASM-NEXT: .vbyte 4, 0xc0000000 # Vector Parameter type = vf
|
||||||
|
;CHECK-ASM-NEXT: .vbyte 2, 0x0000 # Padding
|
||||||
|
;CHECK-ASM-NEXT: # -- End function
|
@ -103,10 +103,10 @@ eh.resume: ; preds = %catch.dispatch
|
|||||||
; ASM: .vbyte 4, 0x00000000 # Traceback table begin
|
; ASM: .vbyte 4, 0x00000000 # Traceback table begin
|
||||||
; ASM: .byte 0x00 # Version = 0
|
; ASM: .byte 0x00 # Version = 0
|
||||||
; ASM: .byte 0x09 # Language = CPlusPlus
|
; ASM: .byte 0x09 # Language = CPlusPlus
|
||||||
; ASM: .byte 0x22 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
|
; ASM: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
|
||||||
; ASM: # +HasTraceBackTableOffset, -IsInternalProcedure
|
; ASM: # +HasTraceBackTableOffset, -IsInternalProcedure
|
||||||
; ASM: # -HasControlledStorage, -IsTOCless
|
; ASM: # -HasControlledStorage, -IsTOCless
|
||||||
; ASM: # +IsFloatingPointPresent
|
; ASM: # -IsFloatingPointPresent
|
||||||
; ASM: # -IsFloatingPointOperationLogOrAbortEnabled
|
; ASM: # -IsFloatingPointOperationLogOrAbortEnabled
|
||||||
; ASM: .byte 0x41 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
|
; ASM: .byte 0x41 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
|
||||||
; ASM: # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved
|
; ASM: # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved
|
||||||
|
@ -112,10 +112,10 @@ entry:
|
|||||||
; CHECK-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
|
; CHECK-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
|
||||||
; CHECK-NEXT: .byte 0x00 # Version = 0
|
; CHECK-NEXT: .byte 0x00 # Version = 0
|
||||||
; CHECK-NEXT: .byte 0x09 # Language = CPlusPlus
|
; CHECK-NEXT: .byte 0x09 # Language = CPlusPlus
|
||||||
; CHECK-NEXT: .byte 0x22 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
|
; CHECK-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
|
||||||
; CHECK-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
|
; CHECK-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
|
||||||
; CHECK-NEXT: # -HasControlledStorage, -IsTOCless
|
; CHECK-NEXT: # -HasControlledStorage, -IsTOCless
|
||||||
; CHECK-NEXT: # +IsFloatingPointPresent
|
; CHECK-NEXT: # -IsFloatingPointPresent
|
||||||
; CHECK-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
|
; CHECK-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
|
||||||
; CHECK-NEXT: .byte 0x41 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
|
; CHECK-NEXT: .byte 0x41 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
|
||||||
; CHECK-NEXT: # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved
|
; CHECK-NEXT: # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved
|
||||||
|
@ -141,6 +141,20 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIParmsType) {
|
|||||||
XCOFFTracebackTable TT3 = *TTOrErr3;
|
XCOFFTracebackTable TT3 = *TTOrErr3;
|
||||||
ASSERT_TRUE(TT3.getParmsType());
|
ASSERT_TRUE(TT3.getParmsType());
|
||||||
EXPECT_EQ(TT3.getParmsType().getValue(), "d, i, f, f");
|
EXPECT_EQ(TT3.getParmsType().getValue(), "d, i, f, f");
|
||||||
|
|
||||||
|
V[6] = 0x04;
|
||||||
|
V[7] = 0x1E;
|
||||||
|
V[8] = 0xAC;
|
||||||
|
V[9] = 0xAA;
|
||||||
|
V[10] = 0xAA;
|
||||||
|
V[11] = 0xAA;
|
||||||
|
Size = sizeof(V);
|
||||||
|
Expected<XCOFFTracebackTable> TTOrErr4 = XCOFFTracebackTable::create(V, Size);
|
||||||
|
ASSERT_THAT_EXPECTED(TTOrErr4, Succeeded());
|
||||||
|
XCOFFTracebackTable TT4 = *TTOrErr4;
|
||||||
|
ASSERT_TRUE(TT4.getParmsType());
|
||||||
|
EXPECT_EQ(TT4.getParmsType().getValue(),
|
||||||
|
"f, f, d, i, i, f, f, f, f, f, f, f, f, f, f, f, f, ...");
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t TBTableData[] = {
|
const uint8_t TBTableData[] = {
|
||||||
@ -205,7 +219,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo) {
|
|||||||
EXPECT_EQ(VecExt.getNumberOfVectorParms(), 2u);
|
EXPECT_EQ(VecExt.getNumberOfVectorParms(), 2u);
|
||||||
EXPECT_TRUE(VecExt.hasVMXInstruction());
|
EXPECT_TRUE(VecExt.hasVMXInstruction());
|
||||||
|
|
||||||
EXPECT_EQ(VecExt.getVectorParmsInfoString(), "vf, vf");
|
EXPECT_EQ(VecExt.getVectorParmsInfo(), "vf, vf");
|
||||||
|
|
||||||
ASSERT_TRUE(TT.getExtensionTable());
|
ASSERT_TRUE(TT.getExtensionTable());
|
||||||
EXPECT_EQ(TT.getExtensionTable().getValue(),
|
EXPECT_EQ(TT.getExtensionTable().getValue(),
|
||||||
@ -216,7 +230,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo) {
|
|||||||
|
|
||||||
TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
|
TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
|
||||||
const uint8_t TBTableData[] = {
|
const uint8_t TBTableData[] = {
|
||||||
0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x00,
|
0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc5, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
|
||||||
0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
|
0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
|
||||||
0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
|
0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
|
||||||
@ -227,7 +241,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
|
|||||||
XCOFFTracebackTable TT = *TTOrErr;
|
XCOFFTracebackTable TT = *TTOrErr;
|
||||||
|
|
||||||
ASSERT_TRUE(TT.getParmsType());
|
ASSERT_TRUE(TT.getParmsType());
|
||||||
EXPECT_EQ(TT.getParmsType().getValue(), "v, i, f, i, d, i");
|
EXPECT_EQ(TT.getParmsType().getValue(), "v, i, f, i, d, i, v, v");
|
||||||
|
|
||||||
ASSERT_TRUE(TT.getVectorExt());
|
ASSERT_TRUE(TT.getVectorExt());
|
||||||
TBVectorExt VecExt = TT.getVectorExt().getValue();
|
TBVectorExt VecExt = TT.getVectorExt().getValue();
|
||||||
@ -239,7 +253,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
|
|||||||
EXPECT_EQ(VecExt.getNumberOfVectorParms(), 3u);
|
EXPECT_EQ(VecExt.getNumberOfVectorParms(), 3u);
|
||||||
EXPECT_TRUE(VecExt.hasVMXInstruction());
|
EXPECT_TRUE(VecExt.hasVMXInstruction());
|
||||||
|
|
||||||
EXPECT_EQ(VecExt.getVectorParmsInfoString(), "vi, vs, vc");
|
EXPECT_EQ(VecExt.getVectorParmsInfo(), "vi, vs, vc");
|
||||||
|
|
||||||
ASSERT_TRUE(TT.getExtensionTable());
|
ASSERT_TRUE(TT.getExtensionTable());
|
||||||
EXPECT_EQ(TT.getExtensionTable().getValue(),
|
EXPECT_EQ(TT.getExtensionTable().getValue(),
|
||||||
@ -496,3 +510,49 @@ TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef64) {
|
|||||||
ExpectErr.takeError(),
|
ExpectErr.takeError(),
|
||||||
FailedWithMessage("csect symbol \".data\" contains no auxiliary entry"));
|
FailedWithMessage("csect symbol \".data\" contains no auxiliary entry"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterType) {
|
||||||
|
const uint8_t TBTableData[] = {0x00, 0x00, 0x22, 0x40, 0x80, 0x00, 0x01,
|
||||||
|
0x05, 0x58, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x40, 0x00, 0x07, 0x61, 0x64, 0x64,
|
||||||
|
0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
|
||||||
|
uint64_t Size = 28;
|
||||||
|
Expected<XCOFFTracebackTable> TTOrErr =
|
||||||
|
XCOFFTracebackTable::create(TBTableData, Size);
|
||||||
|
|
||||||
|
EXPECT_THAT_ERROR(
|
||||||
|
TTOrErr.takeError(),
|
||||||
|
FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
|
||||||
|
"in parseParmsType."));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterTypeWithVecInfo) {
|
||||||
|
const uint8_t TBTableData[] = {
|
||||||
|
0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x10,
|
||||||
|
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
|
||||||
|
0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
|
||||||
|
0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
|
||||||
|
uint64_t Size = 44;
|
||||||
|
Expected<XCOFFTracebackTable> TTOrErr =
|
||||||
|
XCOFFTracebackTable::create(TBTableData, Size);
|
||||||
|
|
||||||
|
EXPECT_THAT_ERROR(
|
||||||
|
TTOrErr.takeError(),
|
||||||
|
FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
|
||||||
|
"in parseParmsTypeWithVecInfo."));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtVecParameterType) {
|
||||||
|
const uint8_t TBTableData[] = {
|
||||||
|
0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
|
||||||
|
0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
|
||||||
|
0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00};
|
||||||
|
uint64_t Size = 44;
|
||||||
|
Expected<XCOFFTracebackTable> TTOrErr =
|
||||||
|
XCOFFTracebackTable::create(TBTableData, Size);
|
||||||
|
|
||||||
|
EXPECT_THAT_ERROR(TTOrErr.takeError(),
|
||||||
|
FailedWithMessage("ParmsType encodes more than ParmsNum "
|
||||||
|
"parameters in parseVectorParmsType."));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user